简体   繁体   中英

Forward declaration of a class nested in in a class template, is it legal?

Is this code legal under 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() { }
};

It compiles with GCC 4.9.3 but fails with GCC 5.3 . Online demo

How can I fix this for GCC 5.3 ?

It's ill-formed according to [temp.param]/9 (emphasis mine):

A default template-argument is a template-argument ([temp.arg]) specified after = in a template-parameter. A default template-argument may be specified for any kind of template-parameter (type, non-type, template) that is not a template parameter pack ([temp.variadic]). A default template-argument may be specified in a template declaration. A default template-argument shall not be specified in the template-parameter-lists of the definition of a member of a class template that appears outside of the member's class. A default template-argument shall not be specified in a friend class template declaration. If a friend function template declaration specifies a default template-argument, that declaration shall be a definition and shall be the only declaration of the function template in the translation unit.

sentry is a member class of Foo . You defined it outside the class, and so it may not specify a default argument for the parameters of Foo . As a general rule of thumb, default arguments should appear only on the primary template declaration.

This rule of thumb is also how your code may be fixed :

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM