0

私は常に、テンプレート化された関数では暗黙的な変換が発生しない可能性があり、引数の型がテンプレート化されたパラメーターの型と正確に一致する必要があると考えていました。そうしないと、テンプレートの引数推定が失敗します。

うーん、どうやら私が間違っていたようです。

次のスニペットを検討してください。

#include <iostream>
#include <type_traits>

template <class T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
class myInt
{
    T val;
public:
    myInt(T val) : val(val) {}

    template <class U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
    friend bool operator < (myInt<T> const &t, myInt<U> const &u)
    {
        return t.val < u.val;
    }
};

int main()
{
    myInt<int> i = 5;
    myInt<int> j = 6;

    // std::cout << (i < 6) << std::endl; // gives out compiler errors
    std::cout << (5 < j) << std::endl; // works!
}

なぜ2番目のstd::cout << (5 < j)作品がうまくいくのか分かりません。ここで暗黙の変換が発生したに違いありません。これは禁止されていると思いました。そして、前者が機能する場合、なぜ機能しないのかはさらにわかりませんstd::cout << (i < 6)!

編集: のコンパイラ エラーstd::cout << (i < 6):

test.cpp: In function ‘int main()’:
test.cpp:23:21: error: no match for ‘operator<’ (operand types are ‘myInt<int>’ and ‘int’)
     std::cout << (i < 6) << std::endl; // gives out compiler errors
                     ^
test.cpp:23:21: note: candidate is:
test.cpp:12:17: note: template<class U, class> bool operator<(const myInt<int>&, const myInt<T>&)
     friend bool operator < (myInt<T> const &t, myInt<U> const &u)
                 ^
test.cpp:12:17: note:   template argument deduction/substitution failed:
test.cpp:23:23: note:   mismatched types ‘const myInt<T>’ and ‘int’
     std::cout << (i < 6) << std::endl; // gives out compiler errors
4

1 に答える 1

1

Uこれが「非対称」である理由は、 と の間に根本的な違いがあるためですT

template <class U, typename =
          typename  std::enable_if<std::is_integral<U>::value>::type>
friend bool operator < (myInt<T> const &t, myInt<U> const &u);

operator<はテンプレートであり、Uこのテンプレートのパラメーターです。ただしT、このテンプレートのパラメーターではありません。Tは実際には別のテンプレート へのパラメータであるため、このコンテキストではmyInt( に) 固定されています。T=int

実際には、次のようになります。

template <class U, /*SFINAE stuff*/>
friend bool operator < (myInt<int> const &t, myInt<U> const &u);

for(5 < j)に変換する方法を知って5いる場合。また、 = `intを推論することで(a ) を簡単に渡すことができます。myInt<int> const &tjmyInt<int>myInt<U> const &uU

しかし、(j<6)に渡す方法がわからないため、機能しません。特に、必要なコンストラクターを使用して適切なものを作成するものをどのように推測できますか? おそらくコンストラクターがあり、コンストラクターがあります。コンパイラは知ることができません。6template<class U> ..... myInt<U> const &uUmyInt<U>myInt<int>stringmyInt<string>int


代わりにこれを行うことができると思います:

/*   *NOT* a template */
friend bool operator < (myInt<T> const &t, myInt<T> const &u);
                         T instead of U ~~~~~~~~~^
于 2015-08-07T11:16:11.100 に答える