私は現在、いくつかの柔軟なコンパイル時の数学ライブラリを作成しようとしていますが、なんとか取り除くことができない置換の失敗に遭遇しました。ここに問題があります:
まず、有理数のクラスを作成します。必要な部分だけを記述します。
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), "");
エラーは次のとおりです(周囲のblablaなしでエラーを保持しただけです):
... 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 ++は、2つの有理数で機能する最初のテンプレート関数を選択し、それで問題ないだろうと思いました。ただし、それでも最後の2つの関数を適用しようとし、実行しようとして失敗したようです。理解できないこと。いくつかの助けを歓迎します:)
編集:rational
コンストラクターexplicit
を使用すると問題が解決するようです。これはすばらしいことです。しかし、なぜ置換がそれほど難しく失敗したのかを知りたいと思っています。