声明模板成员函数返回类型

时间:2015-08-18 03:12:34

标签: c++ typetraits

我有一个简单的特征功能:

template <typename Traits>
struct Cal {
    typedef typename Traits::T T;
    static T f(T a, T b);
};

struct FTraits {
    typedef float T;
};
struct DTraits {
    typedef double T;
};

我可以考虑实现Cal::f的4种方法并指定返回类型。

// option 1. compile. as inline implementation
template <typename Traits>
struct Cal {
    typedef typename Traits::T T;
    static T f(T a, T b) {
        return a+b;
    }
};
// option 2. compile
template <typename Traits>
typename Traits::T Cal<Traits>::f(T a, T b) {
    return a+b;
};
// option 3. does not compile
template <typename Traits>
T Cal<Traits>::f(T a, T b) {
    return a+b;
};
// option 4. compile
template <typename Traits>
auto Cal<Traits>::f(T a, T b) -> T {
    return a+b;
};

我认为选项4是在c ++ 11中添加的,因为选项3在以前的标准中是不可能的。我的问题是,为什么选项3不起作用?具体来说,我想知道返回类型T背后的原因不能命名一个类型,而参数类型T可以命名一个类型。编译器是否在返回和参数类型的不同上下文中工作?另外,为什么c ++ 11选择4而不是选项3?似乎选项3比选项4更直观。

2 个答案:

答案 0 :(得分:1)

即使像C ++这样的复杂语言的编译器仍然需要从头到尾处理文件。

如果template< … >之后的声明以T开头,编译器需要知道T是什么,以便在继续查找之前解析它并确定它是返回类型宣言的其余部分。

基本上,限定符Cal< Traits >::需要在Cal成员的任何不合格使用之前进行语法合理。使用尾随返回类型扩展语言要容易得多,后者在Cal< Traits >::之后立即放置auto,而不是创建用于跳过具有未知标识符的类型名称的启发式方法。

答案 1 :(得分:0)

T是Cal类模板中的typedef。它没有在全球范围内定义。以下应该可以正常作为选项3:

template <typename Traits>
typename Cal<Traits>::T Cal<Traits>::f(T a, T b) {
    return a+b;
};