合法的交换运营商的模板实施
Template implementation for commutative operators, legal?
我试图为我的一个类实现一个交换添加操作员:
struct mytype
{
constexpr mytype(othertype const &);
constexpr mytype operator+(othertype const &rhs) const;
};
template<typename T>
constexpr auto operator+(T const &lhs, mytype const &rhs) -> decltype(rhs + lhs)
{
return rhs + lhs;
}
的想法是,只要右侧是 mytype
。
这与ICC和Visual Studio一起使用,并进入无尽的递归,解决了GCC和Clang上的decltype
(当达到最大模板深度时终止)。
我可以看到,无尽的递归实际上可能更正确,如错误报告中所述:在进行过载分辨率之前需要专业化(因为它是过载分辨率的输入)。
另一方面,商业编译器以某种方式管理(无论是偶然还是故意是有争议的)。
这里的正确行为是什么?
是否有可能避免指定operator+
应该是可交换的类的完整列表?
可编译的示例:
struct othertype {};
struct mytype
{
constexpr mytype() : value(1) { }
constexpr mytype(int v) : value(v) { }
constexpr mytype(othertype const &o) : value(2) { } // 1
constexpr mytype operator+(mytype const &rhs) const
{
return mytype(value + rhs.value);
}
constexpr mytype operator+(othertype const &rhs) const // 2
{
return mytype(value + 2);
}
int value;
};
template<typename T>
constexpr auto operator+(T const &lhs, mytype const &rhs) -> decltype(rhs + lhs)
{
return rhs + lhs;
}
void test()
{
constexpr mytype mine;
constexpr othertype other;
constexpr auto result = other + mine;
static_assert(result.value == 3);
}
当删除转换// 1
时,问题消失了,这在我的用例中无济于事。单独的添加操作员// 2
不足以帮助解决decltype
:重载分辨率应该已经选择了,但是问题发生在过载分辨率之前发生。
无限递归在专门为T = othertype
的模板:将othertype
转换为mytype
的模板之后提供了两侧的mytype
的添加表达式,这可以通过模板再次解决(即使存在非template)。
您可能会用Sfinae限制模板丢弃operator+<mytype>(mytype const &lhs, mytype const &rhs)
:
template<typename T, typename std::enable_if<!std::is_same<T, mytype>::value, int>::type = 0>
constexpr auto operator+(T const &lhs, mytype const &rhs) -> decltype(rhs + lhs)
{
return rhs + lhs;
}
demo
相关文章:
- 呼叫运营商<<临时
- 两个运营商的一些奇怪的冲突<<
- 如何在 CPP 中访问家长的运营商
- 如何明确调用好友流运营商
- 私有运营商删除会触发 GCC 和 Clang 的编译时错误,但不会在 MSVC 上触发编译时错误
- 使用运营商New分配的数据结构是否有任何副作用
- "Inheriting"移动运营商?
- 朋友ostream&运营商<<无法访问私人会员
- 为什么在下面的代码返回类型中是用于运营商重载的类类型
- 范围的枚举(枚举类)关系运营商
- 为什么“操作员”需要const但不是为“运营商&lt;”
- 对这两个分配运营商之间的不同感到困惑
- 我的班级意外加法运营商
- OpenACC - C++"新"运营商问题
- c 对运营商的一致性是新的,有多少重要
- 为什么我不能使私人运营商成为新的并使用默认实现?
- 全球取代所有新运营商
- 包装C 朋友在Cython中的非会员运营商
- 合法的交换运营商的模板实施
- 朋友超载的派生类和基本成员访问的运营商