2016-12-13 78 views
1

我喜欢玩自动和decltype,然后我想知道是否可以用auto来做泛型运算符。事实上,由于C++ 14等可以这样做:泛型重载运算符

decltype(auto) add(auto v1, auto v2) { 
    return v1 + v2; 
} 

不过,我想与含有像这样的值模板类来试试吧:

template<typename T> 
class test { 
public: 
    T value; 
    test(T val) { 
    value = val; 
    } 
}; 

,然后我需要超负荷运营商+像这样一个工作:

template<typename T> 
T operator+(test<T> const& t1, test<T> const& t2) { 
    return t1.value + t2.value; 
} 

这已经相当不错了。不过,我想要一个可以被多个类使用的通用运算符+。像这些:

decltype(t1.value) operator+(auto const& t1, auto const& t2) { 
    return t1.value + t2.value; 
} 

template<typename T> 
T operator+(auto const& t1, auto const& t2) { 
    return t1.value + t2.value; 
} 

它不会编译。

在C++ 14/17中,是否有一种方法可以使泛型重载运算符能够被许多类使用,如我写的那些类?

PS:在这里为您的测试与gcc7快照编译,但不能与铛这似乎不允许代码自动函数原型: link to compiler explorer code

#include <iostream> 

template<typename T> 
class test { 
public: 
    T value; 
    test(T val) { 
    value = val; 
    } 
}; 

template<typename T> 
T operator+(test<T> const& t1, test<T> const& t2) { 
    return t1.value + t2.value; 
} 

decltype(auto) add(auto v1, auto v2) { 
    return v1 + v2; 
} 

int main() { 
    decltype(5) v1 = 5; 
    decltype(v1) v2 = 3; 
    test<decltype(v1)> t(v1); 
    test<decltype(v2)> t2(v2); 

    return add(t, t2); 
} 
+0

* *事实上,因为C++ 14 et可以做到这一点:*“不,你不能。 'auto'只能用作* lambdas *中的参数占位符。这是Concepts TS将其扩展到常规功能。而C++ 14不包括这一点。 –

回答

3

如果我明白你的问题,你可以使用尾随返回类型:

auto operator+(auto const& t1, auto const& t2) -> decltype(t1.value + t2.value) { 
    return t1.value + t2.value; 
} 

对于编译器不接受auto的参数,你可以简单地掉下背对着两个模板参数:

template <typename U, typename V> 
auto operator+(U const& t1, V const& t2) -> decltype(t1.value + t2.value) { 
    return t1.value + t2.value; 
} 

由于@Jarod42在评论中提到的,你可能想使用decltype(t1.value + t2.value)而不是decltype(t1.value)正确处理转换和促销活动。

+0

如果使用-pedantic进行编译,gcc将不会接受auto作为正常函数的参数类型。我建议在这种情况下它是非标准的。 –

+0

@RichardHodges你可能是对的(我不知道这是可能的,但实际上看到这个问题之前......),我提出了一个不使用auto作为参数类型的替代方案。 – Holt

+0

我不知道为什么我没有尝试用汽车换回对不起。 –