嵌套在类模板中的类的前向声明是否合法?

Vio*_*ffe 7 c++ templates language-lawyer c++14 c++17

这个代码合法C++14/17吗?

template <class T1, class T2 >
class Foo
{
public:
    class sentry;
};

template <class T1,class T2 = int>
class Foo<T1,T2>::sentry
{
public:
    ~sentry() { }
};
Run Code Online (Sandbox Code Playgroud)

它与GCC 4.9.3一起编译,但在GCC 5.3中失败. 在线演示

我如何解决GCC 5.3的问题

Sto*_*ica 6

根据[temp.param]/9(强调我的),这是不正确的:

默认模板参数是在模板参数中=后指定的模板参数([temp.arg]).可以为任何类型的模板参数(类型,非类型,模板)指定默认模板参数,该模板参数不是模板参数包([temp.variadic]).可以在模板声明中指定默认模板参数. 默认模板参数不应在出现在成员类之外的类模板成员定义的template-parameter-lists中指定.不应在友元类模板声明中指定默认模板参数.如果友元函数模板声明指定了默认模板参数,则该声明应该是一个定义,并且应该是翻译单元中函数模板的唯一声明.

sentry一个成员类Foo.您在类外部定义了它,因此它可能没有为参数指定默认参数Foo.作为一般经验法则,默认参数应仅出现在主模板声明中.

这个经验法则也是您的代码可以修复的方式:

template <class T1, class T2 = int>
class Foo
{
public:
    class sentry;
};

template <class T1,class T2>
class Foo<T1,T2>::sentry
{
public:
    ~sentry() { }
};
Run Code Online (Sandbox Code Playgroud)