【问题标题】:Forward declaration of a class nested in in a class template, is it legal?嵌套在类模板中的类的前向声明是否合法?
【发布时间】:2019-02-17 11:41:52
【问题描述】:

这段代码在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() { }
};

它使用 GCC 4.9.3 编译,但使用 GCC 5.3 编译失败。 Online demo

我怎样才能为 GCC 5.3 解决这个问题?

【问题讨论】:

    标签: c++ templates c++14 language-lawyer c++17


    【解决方案1】:

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

    默认模板参数是模板参数 ([temp.arg]) 在模板参数中的 = 之后指定。默认模板参数 可以为任何类型的模板参数指定(类型,非类型, 模板)不是模板参数包([temp.variadic])。一种 默认模板参数可以在模板声明中指定。 不应在 类成员定义的模板参数列表 出现在成员类之外的模板。默认值 不应在朋友类模板中指定模板参数 宣言。如果友元函数模板声明指定了一个 默认模板参数,该声明应为定义和 应该是函数模板中唯一的声明 翻译单元。

    sentrya member classFoo。您在类之外定义了它,因此它可能没有为Foo 的参数指定默认参数。作为一般经验法则,默认参数应该只出现在主模板声明中。

    这个经验法则也是你的代码可能是fixed

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

    【讨论】:

    • 我想知道,sentry 类(OP 的情况)是否;将属于专业化的情况!...嗯看起来像棘手的基础知识..
    • @JeJo - 不确定我是否关注你。我引用的段落仅谈到了类外定义,无需将其视为特化(即使部分特化也不允许默认模板参数)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 2010-10-31
    相关资源
    最近更新 更多