如果模板参数确实如此,则仅重载运算符

Dan*_*ins 5 c++ operator-overloading c++14

给定具有单个模板参数 T 的模板类 A,是否可以仅重载 A 中可用于类型 T 的运算符?例如:

template <typename T>
class A
{
public:
    #if hasOperator(T, +=)
    T& operator +=(const T &rhs)
    {
        mValue += rhs;
        return mValue;
    }
    #endif

private:
    T mValue;
}


int main()
{
    A<int> a;
    a += 8; //+= will forward to the += for the int

    struct Test {  /*no operators defined*/ };
    A<Test> b; //+= is not implemented since Test does not implement +=
}
Run Code Online (Sandbox Code Playgroud)

我正在编写一个通用包装类,它的行为需要与模板类型完全一样。因此,如果 T 具有运算符 +=,则 A 将(在编译时)相应地重载 +=。是的,我可以继续在 A 中实现每个运算符,但是当 T 没有某个运算符时编译器会出错。起初我认为模板专业化可能是答案,但这需要对每种类型进行专业化。虽然这可以工作并且需要大量输入,但它不会,因为 A 需要使用任何类型(不仅仅是专门的类型)。

Pra*_*ian 4

使用表达式 SFINAE 将您的operator+重载决策集中删除,除非T定义operator+

template <typename T>
class A
{
private:
    T mValue;
public:
    template<typename U=T>
    auto operator +=(const U &rhs)
        -> decltype(mValue += rhs)
    {
        mValue += rhs;
        return mValue;
    }
};
Run Code Online (Sandbox Code Playgroud)

现场演示

  • @Yakk,我对此可能是错的,但是关于您的第一条评论,只有在*任何*类型集的模板没有有效实例化的情况下,程序不是格式不正确吗?在这种情况下,如果“T”实现了该运算符,则可以实例化它。我对“{}”的事情有点惊讶......我预计它也会失败,但似乎无法[找到办法](http://coliru.stacked-crooked.com /a/7122521cfe7802bc) 来获取它。 (2认同)
  • @Yakk 不需要 `+=` 成为成员。因此,如果存在“noinc&amp; operator+=(noinc&amp;, hacky_type);”,则“A&lt;noinc&gt;::operator+=&lt;hacky_type&gt;”可能是某些“hacky_type”的有效实例化。 (2认同)