我目前正在嘗試編寫一些靈活的編譯時數學庫,並剛剛遇到替代失敗,我無法擺脫。這是問題:替換失敗
首先,我正在寫一個理性的類,我會把唯一需要的部分。
template<typename T>
class rational
{
static_assert(std::is_integral<T>::value, "Can only contain integral values.");
public:
constexpr rational(T numerator, T denominator);
private:
T _numerator;
T _denominator;
};
,並允許該庫是靈活的,我試圖讓一個大量使用SFINAE,以限制操作的函數調用唯一合理的,理性的,理性的積分和積分理性的,但是這將無論積分是什麼和基本類型如何。下面是operator+
比如函數聲明:
template<typename T, typename U>
constexpr
rational<typename std::common_type<T, U>::type>
operator+(const rational<T>& lhs, const rational<U>& rhs);
template<typename T, typename U>
constexpr
typename std::enable_if<std::is_integral<U>::value, rational<typename std::common_type<T, U>::type>>::type
operator+(const rational<T>& lhs, const U& rhs);
template<typename T, typename U>
constexpr
typename std::enable_if<std::is_integral<T>::value, rational<typename std::common_type<T, U>::type>>::type
operator+(const T& lhs, const rational<U> rhs);
這裏是代碼故障段。它不會因爲static_assert
但替代大概是因爲失敗的崩潰:
constexpr auto r1 = rational<int>(1, 2);
constexpr auto r2 = rational<int>(2, 4);
static_assert(r1 + r2 == rational<int>(1, 1), "");
的錯誤是下面(我只保留而不被周圍布拉布拉錯誤):
... required by substitution of 'template<class T, class U> constexpr typename std::enable_if<std::is_integral<T>::value, smath::rational<typename std::common_type<_Tp, _Up>::type> >::type smath::operator+(const T&, smath::rational<U>) [with T = smath::rational<int>; U = int]'
... required from here
... error: operands to ?: have different types 'smath::rational<int>' and 'int'
... required by substitution of 'template<class T, class U> constexpr typename std::enable_if<std::is_integral<U>::value, smath::rational<typename std::common_type<_Tp, _Up>::type> >::type smath::operator+(const smath::rational<T>&, const U&) [with T = int; U = smath::rational<int>]'
... required from here
... error: operands to ?: have different types 'int' and 'smath::rational<int>'
我的猜測是, g ++會選擇與兩個有理數一起工作的第一個模板函數,並且可以。但是,它似乎仍然嘗試應用最後兩個函數,並在嘗試這樣做時失敗。我無法理解。一些幫助將受到歡迎:)
編輯:似乎具有rational
構造explicit
解決問題,這是偉大的。不過,我仍然很想知道替代失敗的原因。
也許你試圖添加一個int到基於模板的變量,它不能解決衝突?你有一個operator +,它的一邊是smath :: rational,另一邊是int?相反呢?由於您使用的是重載的「+」運算符,因此請將每個「a + b」的情況視爲對所述運算符的調用,並相應地驗證類型。 – Ghost2
我的'operator +'函數採用兩個有理數或一個有理數的整數值(無論哪種整數類型)。有一個用於右側的整數值,另一個用於左側的整數值。當我給出一個有理數和一個整數值時,這些斷言很有效。它只是失敗了兩個有理數。 – Morwenn