我创建了一个类似这样的课程.关键是它有一个主模板参数加上一个默认的模板基类.还有一个模板化的复制构造函数......
struct default_base{};
template <typename T, typename TBase=default_base>
class some_class : public TBase{
public:
some_class(){}
template <typename U, typename UBase>
some_class(const some_class<U,UBase>& u){
T t(U());
}
};
int main(){
some_class<int> a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到这个令人讨厌的模糊编译器错误,并且无法发现我的错误...所以我的问题是 - 什么是真的错?我正在使用gcc 4.8.1.
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\stuff.o" "..\\src\\stuff.cpp"
..\src\stuff.cpp: In constructor 'some_class<T, TBase>::some_class(const some_class<U, UBase>&)':
..\src\stuff.cpp:87:10: error: default argument for template parameter for class enclosing 'T t(U (*)())'
T t(U());
^
..\src\stuff.cpp: In function 'int main()':
..\src\stuff.cpp:104:16: error: wrong number of template arguments (1, should be 2)
some_class<int> a;
^
..\src\stuff.cpp:82:7: error: provided for 'template<class T, class TBase> class some_class'
class some_class : public TBase{
^
..\src\stuff.cpp:104:19: error: invalid type in declaration before ';' token
some_class<int> a;
Run Code Online (Sandbox Code Playgroud)
编辑:找到答案,干杯:-)即使我仍然认为它应该编译...这编译...
template <typename T>
struct some_other_class{
some_other_class(){}
template <typename U>
some_other_class(){
T t(U());
}
};
Run Code Online (Sandbox Code Playgroud)
T t(U());
Run Code Online (Sandbox Code Playgroud)
这就是所谓的"最令人烦恼的解析".它是返回T的函数声明,并取出返回U作为参数的nullary函数.想像:
typedef U nullary_function_return_U();
T t(nullary_function_return_U /*param_name*/)
{
return T;
}
Run Code Online (Sandbox Code Playgroud)
您可以通过添加括号来解决此问题:
T t( (U()) );
Run Code Online (Sandbox Code Playgroud)
或者在C++ 11中,您可以使用统一的初始化语法:
T t{U{}};
Run Code Online (Sandbox Code Playgroud)
确实最令人烦恼.错误信息真的很糟糕,无论最烦恼的解析,它应该真的编译,不应该吗?
我在GCC 4.8.1上测试过 - 错误,Clang 3.4 - 好的,MSVC2010 - 好的.我把它减少到最小的情况,在GCC上触发错误:
template <typename = int>
struct Foo
{
Foo()
{
int t(int()); // Error
}
};
int main()
{
int t(int()); // OK
Foo<> a; // Error
}
Run Code Online (Sandbox Code Playgroud)
这看起来像GCC bug.我已经向GCC Bugzilla报告了.
编辑:
Paolo Carlini 2014-07-07 14:11:14 UTC这已经是固定的主线和4.9.1.我正在添加测试用例并关闭错误.