#include<tuple>
#include<iostream>
using namespace std;
class A
{
public:
int v;
A(int a) : v(a){}
operator int (){return v;}
};
class B
{
public:
int v;
B(int a) : v(a + 1) {}
operator int (){return v;}
};
class C
{
public:
int v;
C(int a) : v(a + 2){}
operator int (){return v;}
};
template <typename... Args >
int f(int a, Args... args )
{
tuple<Args...> argstuple1( std::forward<Args>(a)... );
tuple<Args...> argstuple2(Args{a}...);
//The following initialization won't compile
tuple<Args...> argstuple2(Args(a)...);
cout << (int)std::get<2>(argstuple2) << endl;
return 1;
}
int main()
{
f< A, B, C>(5,0,0,0);
}
我想在这里做的是,给定一个值,我有3个不同的类以3种不同的方式处理这个相同的值。我在这里遇到的问题是如何扩展参数包并使用给定的单个值a初始化每个类。
tuple<Args...> argstuple2(Args(a)...);
我认为上面的代码会扩展为
tuple<A, B, C> argstuple2(A(a), B(a), C(a));
看起来编译器并不喜欢这样。 但是,以下所有代码都可以正常编译
tuple<Args...> argstuple2(Args(1)...);
tuple<Args...> argstuple2(Args{a}...);
tuple<Args...> argstuple2(std::forward<Args>(a)...);
我想知道为什么Args(a)......无法扩展? Args(a)......和Args {a} ......有什么区别? std :: forward(a)怎么样......)?
我正在使用gnu 4.7.1
答案 0 :(得分:2)
// now it will
using tuple_args = tuple< Args... >;
tuple_args argstuple3((Args(a))...);
答案 1 :(得分:-1)
clang有一个更好的错误代码:
<source>:36:28: warning: parentheses were disambiguated as a function
declaration [-Wvexing-parse]
tuple<Args...> argstuple3(Args(a)...);
^~~~~~~~~~~~
<source>:36:29: note: add a pair of parentheses to declare a variable
tuple<Args...> argstuple3(Args(a)...);
^
( )
vexing-parse应该听起来很熟悉。 它被视为功能声明。
这个argstuple3看起来像一个函数名,它返回一个元组&lt;&gt;并有参数Args(a)。
这个Args(a)被视为返回'Args'(类型)并被传递'a'的函数指针
编译器会将其视为此类
tuple<int> argtuple3(int());
如果你试一试,你会看到同样的错误。
解决此问题的另一个选择:
tuple<Args...> argstuple3{Args(a)...};