模板VS 2005版中的模板

template inside template VS 2005 issue?

本文关键字:VS 2005版 模板      更新时间:2023-10-16

下面的代码(它用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编译器的编译错误:

错误C2976:"QVariantConstructor::FilteredConstructor":模板参数太少1> 与1>[1> Filter="匿名命名空间"::CoreTypesFilter1> ]1> 请参阅"QVariantConstructor::FilteredConstructor"的声明1> 与1>[1> Filter="匿名命名空间"::CoreTypesFilter1> ]1> 请参阅对正在编译的函数模板实例化"void QVariantConstructor::delegate(const T*)"的引用1> 与1>[1> Filter="匿名命名空间"::CoreTypesFilter,1> T=字符1> ]1> 错误C2514:"QVariantConstructor::FilteredConstructor":类没有构造函数1> 与1>[1> Filter="匿名命名空间"::CoreTypesFilter1> ]1> 请参阅"QVariantConstructor::FilteredConstructor"的声明1> 与1>[1> Filter="匿名命名空间"::CoreTypesFilter1> ]

我快速阅读了该标准的相关章节,问题似乎归结为您如何阅读ISO/IEC 14882:2003第14.1节第9段

默认模板参数是在template-parameter中的=之后指定的template-argument(14.3)。可以为任何类型的template-parameter(类型、非类型、模板)指定默认template-argument。默认template-argument可以在类模板声明或类模板定义中指定。不应在函数模板声明或函数模板定义中指定默认template-argument,也不应在类模板成员定义的template-parameter-list中指定。不应在友元模板声明中指定默认template-argument

严格来说,这似乎意味着你的代码是非法的。然而,大多数实现似乎将其解释为已经声明的模板成员的定义

健康警告,这是基于第一次阅读。我的答案很可能是错误的或不完整的,请纠正我。