【问题标题】:Porting code from gcc to clang将代码从 gcc 移植到 clang
【发布时间】:2013-03-06 10:52:08
【问题描述】:

您好,我正在尝试在 clang 3.2-9 下编译我的代码,这是我无法编译的简化示例:

template<template <class>class Derived, typename Type>
class Foo
{
    public:
        Foo(){}
};

template<typename Type>
class Bar
    : public Foo<Bar, Type>
{
    public:
        Bar()
            : Foo<Bar, Type>()
        {}
};

int main()
{
    Bar<int> toto;
}

这是 clang 告诉我的错误:

test.cpp:14:19: error: template argument for template template parameter must be a class template
            : Foo<Bar, Type>()
                  ^
test.cpp:14:15: error: expected class member or base class name
            : Foo<Bar, Type>()
              ^
test.cpp:14:15: error: expected '{' or ','
3 errors generated.

它在 gcc 4.7.2 下编译没有任何问题。而且我无法获得正确的语法以使其在clang下工作。 谁能帮帮我,我有点卡住了......

【问题讨论】:

    标签: c++ templates parameters c++11 clang


    【解决方案1】:

    只需为您的类模板使用完全限定名称:

    template<template <class> class Derived, typename Type>
    class Foo
    {
        public:
            Foo(){}
    };
    
    template<typename Type>
    class Bar
        : public Foo<::Bar, Type>
    //               ^^^^^
    {
        public:
            Bar()
                : Foo<::Bar, Type>()
    //                ^^^^^
            {}
    };
    
    int main()
    {
        Bar<int> toto;
    }
    

    问题是在Bar 内部,名称Bar 指的是类本身,即Bar 类模板(即Bar&lt;Type&gt;)的实例化,而不是模板本身。

    你可以看到这个例子编译here

    【讨论】:

    • 你知道 gcc 是否应该接受我的版本,还是它对标准过于宽容,还是 clang 正确触发了这个错误? (如果可能的话,你知道标准的哪一部分谈到了这个问题吗?)谢谢
    • @b3nj1:你使用的是什么版本的 GCC?
    • 我使用 gcc 4.7.2。哦,clang 要求在 <:: ::>
    • @b3nj1:GCC 4.7.2 也需要一个空格,但 GCC 4.8.0(测试版)和 Clang 3.2 都不需要
    • 我认为G++接受原代码是错误的。标准的相关部分是 9 [class]/2,它定义了 injected-class-name。该空间不应该是必需的,但 G++ 4.7 没有实现 [lex.pptoken]/3
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 2018-03-24
    相关资源
    最近更新 更多