Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 声明模板成员函数返回类型_C++_Typetraits - Fatal编程技术网

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

C++ 声明模板成员函数返回类型,c++,typetraits,C++,Typetraits,我有一个简单的traits函数: 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; }; 我相信选项4是在c++11中添加的,因为选项3在以前的标准中是不可能的。我的问

我有一个简单的traits函数:

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;
};

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

即使是C++等复杂语言的编译器,仍然需要从开始到结束处理文件。

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


本质上,限定符
Cal
需要在语法上位于
Cal
成员的任何非限定用法之前。使用尾随返回类型扩展语言要容易得多,它将
Cal
放在
auto
之后,而不是创建一个跳过未知标识符的类型名称的启发式方法。

T是Cal类模板中的一个typedef。它不是在全局范围内定义的。作为选项3,以下各项可以正常工作:

template <typename Traits>
typename Cal<Traits>::T Cal<Traits>::f(T a, T b) {
    return a+b;
};
模板
类型名称Cal::T Cal::f(TA,TB){
返回a+b;
};

因此很难推断返回类型,因为它是在函数签名和正文之前指定的。在c++11中,尾部返回类型很容易推断,因为它是在函数签名之后指定的。我说得对吗?但是,我记得C++使用LALR,因此能够看到一个令牌在前面——这是返回类型的函数签名。那么,技术上是否可能以这种方式实现(当然,它仍然很难)?@ XOSP7ToM C++没有完全被标准化中列出的语法规则所定义;它只有EBNF,其中包含由标识符形成的产品的上下文相关语义规则。有些编译器是经过“修改”的LALR。在您的示例中,一个前瞻标记就足够了,但这不是一般情况。顺便说一句,演绎是另一回事;在您的示例程序中根本没有演绎。
template <typename Traits>
typename Cal<Traits>::T Cal<Traits>::f(T a, T b) {
    return a+b;
};