【发布时间】:2014-02-23 03:02:48
【问题描述】:
鉴于此代码:
#include <iostream>
template<typename... Args> class X;
template<typename T>
class X<T> {
public:
T value;
X(T value_) : value(value_) {}
};
template<typename T, typename... Args>
class X<T, Args...> : public X<Args...> {
public:
T value;
X(T value_, Args... args) : value(value_), X<Args...>(args...) {}
};
template<typename T>
std::ostream& operator <<(std::ostream& stream, const X<T>& value_) {
stream << value_.value;
return stream;
}
template<typename T, typename... Args>
std::ostream& operator <<(std::ostream& stream, const X<T, Args...>& value_) {
stream << value_.value << " " << static_cast<X<Args...> const& >(value_);
return stream;
}
class Person : public X<std::string, int>{
public:
Person(std::string name, int age) : X<std::string, int>(name, age) {}
};
int main()
{
std::cout << Person("Me", 35) << std::endl;
return 0;
}
使用 'g++ -std=c++11 main.cpp' 使用 gcc 4.7.2 编译,执行时给出以下输出:
35
我期待它打印出来:
Me 35
因为它应该首先匹配 Person 的直接超类而不是其超超类的 operator 行为的 int,而不是作为直接超类 X<:string int> 行为的两个项目。这是预期的吗?
【问题讨论】:
-
我怀疑和clang++ agrees:
<< static_cast<X<Args...> >(value_)中的运算符<<模棱两可:两个函数模板都是可行的,具有相同的等级,据我所知,两者都不是更专业的(尽管有一个额外的参数包!)。请参阅 [temp.func.order]/5 中的注释 -
规范性参考:[temp.deduct.partial]/3 “用于确定排序的类型取决于完成部分排序的上下文:- 在函数调用的上下文中,使用的类型是那些函数调用有参数的函数参数类型。" [强调我的]
-
这似乎是 gcc 的一个错误。 VC++ 2013 CTP 可以如您预期的那样产生正确的结果。例如输出是“我 35”
-
@xmllmx 太好了。现在我们有了三个编译器和三种不同的行为。要么在标准中未指定(或未定义),要么其中至少有两个存在错误。
标签: c++ c++11 casting variadic-templates implicit-conversion