2016-12-13 117 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

我不知道爲什麼我沒有嘗試用汽車換回對不起。 –