晚期默认模板参数声明中的clang ++错误

anx*_*eux 7 c++ templates clang++

下面的代码用g ++编译好,但不能用clang ++(3.6)编译:

// Forward declaration:
template <class S, class T>
struct Base;

template <class T>
struct BaseFriend {
    friend struct Base<int, T>;
};

// Actual declaration:
template <class S, class T = int>
struct Base {
    void foo() {}
};

struct DerivedFriend : BaseFriend<int> {};

struct Derived : Base<int> {
    void foo(int) {
        Base<int>::foo();
    }
};
Run Code Online (Sandbox Code Playgroud)

Derived::foo定义中出错:

error: too few template arguments for class template 'Base'
    Base<int>::foo();
    ^
test.cpp:3:8: note: template is declared here
struct Base;
       ^
Run Code Online (Sandbox Code Playgroud)

经过一些小修复后,错误消失了,例如:

  1. 如果在前向声明中定义了默认模板参数而不是实际声明.
  2. 或者如果DerivedFriend没有使用.

但是,原始代码有什么问题?

Bar*_*rry 4

绝对是一个 clang bug,看起来像#10147。标准明确允许 [temp.param]/10:

\n\n
\n

可与模板声明或定义一起使用的默认模板参数集是通过以相同的方式合并定义中的默认参数(如果在范围内)和范围内的所有声明来获得的。\n 默认函数参数是(8.3 .6). [ 例子:

\n\n
template<class T1, class T2 = int> class A;\ntemplate<class T1 = int, class T2> class A;\n
Run Code Online (Sandbox Code Playgroud)\n\n

相当于

\n\n
template<class T1 = int, class T2 = int> class A;\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\x94结束示例]

\n
\n