C++17 - 可变参数模板参数 - 使用模板化参数对 return 值调用 class 方法
C++17 - variadic template arguments - call class method on return value from previous with templated argument
我有这个代码:
struct Foo{
int sum;
Foo() : sum(0) {}
Foo(int x) : sum(x) {}
Foo bar(int x){
return Foo(sum + 1);
}
Foo bar(std::vector<int> x){
return Foo(sum + 1);
}
Foo bar(const char* str){
return Foo(sum + 1);
}
};
template <typename ... T>
int foo(T ... args){
Foo foo;
//(foo.bar(args), ...);
return foo.sum;
}
int main() {
foo(1, 2, "hello", std::vector<int>());
return 0;
}
我想创建这样的调用层次结构:
Foo foo;
foo = foo.bar(1);
foo = foo.bar(2);
foo = foo.bar("hello");
基于可变模板参数 args
。
我正在查看折叠表达式,但它似乎无法满足我的需要。我可以折叠要单独调用的方法,但不能根据上一个的结果调用下一个。
有什么方法可以做到这一点吗?
您可以为此使用折叠表达式。
((foo = foo.bar(args)), ...);
我们需要在赋值周围添加一个额外的 ()
以使编译器接受语法。
我假设这就是你想要的?我真的不知道代码应该做什么...
编辑:
正如@AVH 指出的那样,在这里进行左折或右折会对顺序产生影响。上面的右折叠将从最后一个参数开始调用成员函数并向后工作。左折可能是你想要的,反之亦然。
(..., (foo = foo.bar(args)));
编辑 2:
最后证明逗号运算符强制执行从左到右的计算,所以在这种情况下,我们如何折叠表达式实际上并不重要。如果我们折叠其他东西,那么 ,
可能很重要。
这是一个通用的 for-each-in-pack 函数:
template<class F, class...Args>
constexpr F for_each(F f, Args&&...args) {
std::initializer_list<int>{((void)f(std::forward<Args>(args)), 0)...};
return f;
}
取自here。将其与 lambda 一起使用:
template <typename ... T>
int foo(T&& ... args){
Foo foo;
for_each([&](auto&& x){ foo = foo.bar(std::forward<decltype(x)>(x));}
, std::forward<T>(args) ...>);
return foo.sum;
}
这与公认的解决方案基本相同,但抽象了功能。
我有这个代码:
struct Foo{
int sum;
Foo() : sum(0) {}
Foo(int x) : sum(x) {}
Foo bar(int x){
return Foo(sum + 1);
}
Foo bar(std::vector<int> x){
return Foo(sum + 1);
}
Foo bar(const char* str){
return Foo(sum + 1);
}
};
template <typename ... T>
int foo(T ... args){
Foo foo;
//(foo.bar(args), ...);
return foo.sum;
}
int main() {
foo(1, 2, "hello", std::vector<int>());
return 0;
}
我想创建这样的调用层次结构:
Foo foo;
foo = foo.bar(1);
foo = foo.bar(2);
foo = foo.bar("hello");
基于可变模板参数 args
。
我正在查看折叠表达式,但它似乎无法满足我的需要。我可以折叠要单独调用的方法,但不能根据上一个的结果调用下一个。
有什么方法可以做到这一点吗?
您可以为此使用折叠表达式。
((foo = foo.bar(args)), ...);
我们需要在赋值周围添加一个额外的 ()
以使编译器接受语法。
我假设这就是你想要的?我真的不知道代码应该做什么...
编辑: 正如@AVH 指出的那样,在这里进行左折或右折会对顺序产生影响。上面的右折叠将从最后一个参数开始调用成员函数并向后工作。左折可能是你想要的,反之亦然。
(..., (foo = foo.bar(args)));
编辑 2:
最后证明逗号运算符强制执行从左到右的计算,所以在这种情况下,我们如何折叠表达式实际上并不重要。如果我们折叠其他东西,那么 ,
可能很重要。
这是一个通用的 for-each-in-pack 函数:
template<class F, class...Args>
constexpr F for_each(F f, Args&&...args) {
std::initializer_list<int>{((void)f(std::forward<Args>(args)), 0)...};
return f;
}
取自here。将其与 lambda 一起使用:
template <typename ... T>
int foo(T&& ... args){
Foo foo;
for_each([&](auto&& x){ foo = foo.bar(std::forward<decltype(x)>(x));}
, std::forward<T>(args) ...>);
return foo.sum;
}
这与公认的解决方案基本相同,但抽象了功能。