clang拒绝模板`/`运算符,但gnu c接受它
发布时间:2020-12-16 10:03:34 所属栏目:百科 来源:网络整理
导读:在科学编程的单元管理环境中,我正在管理以下课程: template class UnitNameclass Quantity { double value;public: Quantity(double val = 0) : value(val) {} Quantity(const Quantity ) {} Quantity operator = (const Quantity ) { return *this; } doub
在科学编程的单元管理环境中,我正在管理以下课程:
template <class UnitName> class Quantity { double value; public: Quantity(double val = 0) : value(val) {} Quantity(const Quantity &) {} Quantity & operator = (const Quantity &) { return *this; } double get_value() const noexcept { return value; } operator double() const noexcept { return value; } template <class SrcUnit> Quantity(const Quantity<SrcUnit> &) { // here the conversion is done } template <class SrcUnit> Quantity & operator = (const Quantity<SrcUnit> &) { // here the conversion is done return *this; } template <class TgtUnit> operator TgtUnit() const { TgtUnit ret; // here the conversion is done return ret; } template <class U,class Ur> Quantity<Ur> operator / (const Quantity<U> & rhs) const { return Quantity<Ur>(value / rhs.value); } }; 虽然课程要复杂得多,但我认为我提供了足够的信息来描述我的问题: 现在考虑以下代码段: struct km_h {}; struct Km {}; struct Hour {}; Quantity<km_h> compute_speed(const Quantity<Km> & dist,const Quantity<Hour> & time) { Quantity<km_h> v = dist/time; return v; } 这段代码被gnu c编译器接受,运行良好.调用最后一个模板运算符. 但它被clang编译器(v 3.8.1)拒绝,并带有以下消息: test-simple.cc:53:26: error: use of overloaded operator '/' is ambiguous (with operand types 'const Quantity<Km>' and 'const Quantity<Hour>') Quantity<km_h> v = dist/time; ~~~~^~~~~ test-simple.cc:53:26: note: built-in candidate operator/(__int128,unsigned long long) test-simple.cc:53:26: note: built-in candidate operator/(unsigned long,long double) 所以我的问题是:为什么clang拒绝它?是一个有效的代码?或者gnu c应该拒绝它? 在代码有效的情况下,如何修改它以便clang接受它? 解决方法
我相信铿锵是拒绝你的代码?的权利,但gcc实际上并没有做你想要的(dist和时间都可以隐含地转换为double?而gcc认为内置运算符/(double,double)是最好的候选者).问题是,你写道:
template <class U,class Ur> Quantity<Ur> operator / (const Quantity<U> & rhs) const 什么是Ur?这是一个非推断的上下文 – 所以试图调用此运算符只是dist / time是一个演绎失败.你的候选人从未被考虑过.为了实际使用它,您必须明确提供Ur,如下所示: dist.operator/<Hour,km_h>(time); // explicitly providing Ur == km_h 由于这很糟糕,你不能将Ur推断为模板参数 – 你必须自己提供它作为两个单元的一些元函数: template <class U> Quantity<some_mf_t<UnitName,U>> operator/(Quantity<U> const& ) const; 与some_mf_t一起定义. ?你有operator double()和template< class T>运算符T(),这意味着所有内置运算符都是同样可行的候选者(它们都是非模板,完全匹配). ?让操作符double()类型失败了写入类型安全单元的目的,不是吗? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |