模板二元运算符不明确?
Ambiguous template binary operators?
考虑以下代码
namespace std {
struct type1 {/* Definition */};
template <class T> constexpr T operator+(const type1& x1, const T& x);
template <class T> constexpr T operator+(const T& x, const type1& x1);
}
namespace other {
struct type2 {/* Definition */};
template <class T> constexpr T operator+(const type2& x2, const T& x);
template <class T> constexpr T operator+(const T& x, const type2& x2);
}
int main(int argc, char** argv)
{
std::type1 var1;
other::type2 var2;
auto x = var1 + var2; // What will happen here?
}
在线auto x = var1 + var2
会发生什么?
这是定义好的行为吗?
这是否意味着标准库永远不会只在一侧使用模板定义泛型运算符以避免使用冲突?
此代码导致未定义的行为。不允许将您自己的东西添加到 namespace std;
,现有模板的显式特化除外。
您应该会在符合标准的编译器上遇到不明确的运算符错误。
您的程序格式错误,因为两个版本的重载都符合候选条件。
根据depended name look up(a.k.a Koenig Lookup)定义明确的规则。除了通常的非限定名称查找所考虑的范围和名称空间之外,编译器还将在 operator+
参数的名称空间中查找函数名称。
因此,编译器会将匹配的重载运算符(即来自命名空间 std
和 other
)添加到重载集中。
因此,您将收到不明确的调用错误。
考虑以下代码
namespace std {
struct type1 {/* Definition */};
template <class T> constexpr T operator+(const type1& x1, const T& x);
template <class T> constexpr T operator+(const T& x, const type1& x1);
}
namespace other {
struct type2 {/* Definition */};
template <class T> constexpr T operator+(const type2& x2, const T& x);
template <class T> constexpr T operator+(const T& x, const type2& x2);
}
int main(int argc, char** argv)
{
std::type1 var1;
other::type2 var2;
auto x = var1 + var2; // What will happen here?
}
在线
auto x = var1 + var2
会发生什么?这是定义好的行为吗?
这是否意味着标准库永远不会只在一侧使用模板定义泛型运算符以避免使用冲突?
此代码导致未定义的行为。不允许将您自己的东西添加到 namespace std;
,现有模板的显式特化除外。
您应该会在符合标准的编译器上遇到不明确的运算符错误。 您的程序格式错误,因为两个版本的重载都符合候选条件。
根据depended name look up(a.k.a Koenig Lookup)定义明确的规则。除了通常的非限定名称查找所考虑的范围和名称空间之外,编译器还将在 operator+
参数的名称空间中查找函数名称。
因此,编译器会将匹配的重载运算符(即来自命名空间 std
和 other
)添加到重载集中。
因此,您将收到不明确的调用错误。