方法定义期间返回类型中需要的模板参数

kir*_*kun 5 c++ templates

有谁知道为什么返回类型需要模板参数,而在定义模板方法时不需要参数类型?一个例子:

template<typename T>
struct Car {
  Car drive(Car);  // will be defined after the template declaration.
};

// Attempt #1: does not compile.
// Error: use of class template Car requires template arguments
template<typename T>
inline Car Car<T>::drive(Car) {}

// Attempt #2: compiles!  
// The only difference is the use of template argument in return type.
// However, note that the argument to func does not require template argument!
template<typename T>
inline Car<T> Car<T>::drive(Car) {}
Run Code Online (Sandbox Code Playgroud)

不确定为什么返回类型需要模板参数,但参数类型不需要.当尝试#1失败时,我期待尝试#2也失败并且预计我需要:

template<typename T>
inline Car<T> Car<T>::drive(Car<T>) {}  // but no need to go this far.
Run Code Online (Sandbox Code Playgroud)

但尝试#2工作!

这种行为有充分的理由吗?

GMa*_*ckG 9

首先,你承认这没有意义:Car c;对吧?Car必须有模板参数.这就是你需要在返回类型和类名上指定它的原因.

但范围分辨率运营商(后::),Car<T>注入Car*,所以Car是一个别名Car<T>.但这只发生在范围内Car<T>,这就是为什么你需要它在其他地方而不是之后::.当然,您可以自由地自己明确指定参数.


*此功能更好地解释如下:

template <typename T>
struct foo
{
    // as if the compiler did this:
    typedef foo<T> foo; // (of course, actually illegal)
};
Run Code Online (Sandbox Code Playgroud)

foo是的范围内可用的foo<T>foo<T>.但是,在范围解析运算符之后,该范围可供使用,并且模板参数是可选的.


小智 2

这是因为方法的参数类型是使用类作用域推导的,但如果这些方法是在类作用域之外定义的,则返回类型是从定义类的同一作用域推导的。这对于一切都是如此,而不仅仅是模板。要添加到您的示例中,以下内容将无法编译:

class Foo
{
    typedef int Bar;

    Bar foo () const;
};

Bar
Foo::foo () const
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

...要解决这个问题,您必须准确地告诉 Bar 来自 Foo 的范围:

Foo::Bar
Foo::foo () const
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)