我每周都在看 Jason Turner C ,偶然發現了這段代碼片段。
template<typename... B>
struct Visitor: B...{
template<typename... T>
Visitor(T&&...t): B(std::forward<T>(t))...{}
using B::operator()...;
};
template<typename...T>
Visitor(T...) -> Visitor<std::decay_t<T>...>;
int main(){
std::array<std::variant<double, int, std::string>, 6> a{3.2, 2, 4, 6, 2.4, "foo"};
int intTotal = 0;
double doubleTotal = 0.0;
Visitor visitor {[&intTotal](const int i){intTotal = i;},
[&doubleTotal](const double d) { doubleTotal = d;},
[](const std::string& c) { }};
std::for_each(begin(a), end(a), [&visitor](const auto &v) {std::visit(visitor, v);});
std::cout << intTotal << " " << doubleTotal << std::endl;
}
我可以擺脫完美的轉發以及扣除指南。這不被認為是 C 中的最佳實踐嗎?在什么情況下效率較低?
template<typename... B>
struct Visitor: B...{
Visitor(const B&... b): B(b)... { }
using B::operator()...;
};
e
uj5u.com熱心網友回復:
我可以擺脫完美轉發
通過 const 參考傳遞將復制 lambda,而不是移動它們。
在您的情況下并不重要,但如果 lambdas 按值捕獲事物,這將很重要。如果 lambda 的復制成本很高,則可能會損害性能,或者如果無法復制 lambda(因為它們具有不可復制的狀態,例如[x = std::make_unique<int>()](){}),則會導致編譯錯誤。
我可以擺脫...的扣除指南。
如果您通過 const 參考傳遞,是的。但是,如果您通過轉發參考,則不會。
具有一組獨立模板引數的建構式是一個問題。如果你使用相同的模板引數(并且繼承自std::decay_t<B>...),它仍然不起作用,因為內置的推導指南拒絕進行完美轉發。如果您傳遞左值,則模板引數推導將不起作用。
一個更好的問題是為什么要有一個建構式。如果您洗掉它,該型別將變為聚合,并且一切都會像以前一樣繼續作業。
它甚至可以讓你洗掉演繹指南(除了 Clang 還不支持)。
uj5u.com熱心網友回復:
Visitor(const B&... b)
現在,此建構式的所有引數都將是const參考...
: B(b)...
...并且如果這些子類的建構式中的任何一個采用非const參考的相應引數,則這將是格式錯誤的并且無法編譯。
class Foo {
public:
Foo(int &n) {}
};
嘗試在此類中使用您的訪問者,看看它是否有效。你的模板實體的建構式應該是這樣的
Visitor(const int &n) : Foo(n) {}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/450648.html
