4

下面的代码(它用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> 过滤器=`匿名命名空间'::CoreTypesFilter
1>]
1> 参见 'QVariantConstructor::FilteredConstructor' 的声明
1> 与
1> [
1> 过滤器=`匿名命名空间'::CoreTypesFilter
1>]
1> 参见正在编译的函数模板实例化 'void QVariantConstructor::delegate(const T *)' 的参考
1> 与
1> [
1> 过滤器=`匿名命名空间'::CoreTypesFilter,
1> T=字符
1>]
1> 错误 C2514: 'QVariantConstructor::FilteredConstructor' : 类没有构造函数
1> 与
1> [
1> 过滤器=`匿名命名空间'::CoreTypesFilter
1>]
1> 参见 'QVariantConstructor::FilteredConstructor' 的声明
1> 与
1> [
1> 过滤器=`匿名命名空间'::CoreTypesFilter
1>]
4

1 回答 1

0

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

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

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

健康警告,这是基于初读。我的回答很可能是错误的或不完整的,请纠正我。

于 2013-09-03T21:32:56.197 回答