gpt4 book ai didi

c++ - 模板化运算符重载的奇怪错误

转载 作者:可可西里 更新时间:2023-11-01 16:10:15 24 4
gpt4 key购买 nike

当我编译以下代码片段时,出现了 clang 编译器错误,但 g++/MSVC 却没有:

#include <string>

template<typename T> struct Const {
explicit Const(T val) : value(val) {}
T value;
};

template<typename T> struct Var {
explicit Var(const std::string &n) : name(n) {}

std::string name;
};

template<typename L, typename R> struct Greater {
Greater(L lhs, R rhs) : left(lhs), right(rhs) {}

L left;
R right;
};

template<typename L>
Greater<L, Const<int> > operator > (L lhs, int rhs) {
return Greater<L, Const<int> >(lhs, Const<int>(rhs));
}

template<typename R>
Greater<Const<int>, R> operator > (int lhs, R rhs) {
return Greater<Const<int>, R>(Const<int>(lhs), rhs);
}

Var<double> d("d");

int main() {
d > 10;
return 0;
}

报错如下:

error: overloaded 'operator>' must have at least one parameter of
class or enumeration type
Greater<Const<int>, R> operator > (int lhs, R rhs) {
^
./val.h:31:24: note: in instantiation of function template specialization
'operator><int>' requested here
Greater<Const<int>, R> operator > (int lhs, R rhs) {
^
1 error generated.

这是关于未使用的运算符函数。相反,如果我写 10 > d 而不是 d > 10,那么我会得到关于另一个运算符 > 函数的相同错误。以上在 gcc 4.4.6 和 VS2012 下编译良好。我的错误是什么?

谢谢。

最佳答案

Clang 是对的:运算符重载至少需要一个类或枚举类型参数,否则程序格式错误 (13.5/1)。要了解为什么会出现此错误,我们必须解析更多标准法律术语。

回想一下名称查找、参数推导和重载解析的三位一体。第一步找到两个重载的operator> .第二步推导出每个版本的模板参数。您可能认为第二个重载会成为 SFINAE 规则 (14.8.2) 的牺牲品,因此只有第一个重载可以存活到第三步。但是,没有替换失败(例如缺少嵌套类型定义),而是非法构造(参见前面提到的 13.5/1)。这本身就导致程序格式错误 (14.3/6)

6 If the use of a template-argument gives rise to an ill-formed construct in the instantiation of a template specialization, the program is ill-formed.

在 14.8.3 中提到对推导参数的检查发生在重载决策之前,因此您的首选运算符没有机会被选中。

作为 C++03 变通方案,您可以定义两个 friend 非模板 operator>在你的里面Var<T>类模板。这些将作为具有一个类类型参数的非模板函数注入(inject)周围(在本例中为全局)命名空间,因此不应发生上述错误。

关于c++ - 模板化运算符重载的奇怪错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18596412/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com