下面的代码(用clang和gcc编译好了)。问题是此代码违反了C ++ 03标准, 或者这是VS 2005的错误?如果这是错误,任何解决方法?
更新:我找到了解决方法,使用了前瞻声明:
//forward declaration
template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
struct FilteredConstructor;
//implementation
template<typename T>
class FilteredConstructor<T, true> {/*code here*/};
但是关于有效或无效此类代码的问题仍然符合标准
namespace {
struct CoreTypesFilter {
template<typename T> struct Acceptor {
static const bool IsAccepted = false;
};
};
}
template<class Filter>
class QVariantConstructor {
template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
struct FilteredConstructor {
FilteredConstructor(const QVariantConstructor &tc) {}
};
template<typename T>
struct FilteredConstructor<T, /* IsAcceptedType = */ false> {
FilteredConstructor(const QVariantConstructor &tc) {}
};
public:
template<typename T>
void delegate(const T*)
{
FilteredConstructor<T> tmp(*this);
}
};
//comment or uncomment them to build on VS or linux
#define _TCHAR char
#define _tmain main
int _tmain(int argc, _TCHAR* argv[])
{
QVariantConstructor<CoreTypesFilter> vc;
vc.delegate("test");//this line trigger compile error
return 0;
}
VS 2005编译器的编译错误:
error C2976: 'QVariantConstructor::FilteredConstructor' : too few template arguments 1> with 1> [ 1> Filter=`anonymous-namespace'::CoreTypesFilter 1> ] 1> see declaration of 'QVariantConstructor::FilteredConstructor' 1> with 1> [ 1> Filter=`anonymous-namespace'::CoreTypesFilter 1> ] 1> see reference to function template instantiation 'void QVariantConstructor::delegate(const T *)' being compiled 1> with 1> [ 1> Filter=`anonymous-namespace'::CoreTypesFilter, 1> T=char 1> ] 1> error C2514: 'QVariantConstructor::FilteredConstructor' : class has no constructors 1> with 1> [ 1> Filter=`anonymous-namespace'::CoreTypesFilter 1> ] 1> see declaration of 'QVariantConstructor::FilteredConstructor' 1> with 1> [ 1> Filter=`anonymous-namespace'::CoreTypesFilter 1> ]
答案 0 :(得分:0)
我快速阅读了标准的相关部分,问题似乎归结为您如何阅读ISO / IEC 14882:2003第14.1节第9段
默认模板参数是在template-argument
=
后指定的template-parameter
(14.3)。可以为任何类型的template-argument
(类型,非类型,模板)指定默认template-parameter
。可以在类模板声明或类模板定义中指定默认template-argument
。在函数模板声明或函数模板定义 中,template-argument
中,不应指定默认的template-parameter-list
类模板成员的定义 。不应在朋友模板声明中指定默认template-argument
。
严格来说,这似乎意味着您的代码是非法的。但是,大多数实现似乎都将此解释为已经声明的模板成员的定义。
健康警告,这是基于一读。我的回答可能错误或不完整,请纠正我。