有谁知道为什么返回类型需要模板参数,而在定义模板方法时不需要参数类型?一个例子:
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工作!
这种行为有充分的理由吗?
首先,你承认这没有意义: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)