1

次のように定義されたテンプレートクラスに対して、非メンバー関数isHomogenous(Triple triple)を実装する必要があります。

template <typename T1, typename T2, typename T3>
    class Triple
{
public:
    Triple()
    { }
    Triple(const T1 &a, const T2 &b, const T3 &c) : a(a), b(b), c(c)
    { }
...

isHomogenous関数は、パラメーターtripleの3つの値すべてが同じタイプであるかどうかを示すbool値を返す必要があります。私が試してみました:

template <typename T> bool isHomogenous(Triple<T, T, T> triple) {
    return true;
}

template <typename T1, typename T2, typename T3> bool isHomogenous(Triple<T1, T2, T3> triple) {
    return false;
}

これはうまくいきません、解決策について私にヒントを与えることができますか?

4

3 に答える 3

8

関数テンプレートを部分的に特殊化することはできません。

1つの代替方法は、それをクラステンプレートの静的メンバー関数(またはあなたの場合は単なる値!)として定義し、次に…のような通常の関数テンプレートラッパーを提供することです。

#include <type_traits>

template< class T1, class T2, class T3 >
struct Blah {};

namespace detail {
    template< class T1, class T2, class T3 >
    struct IsHomogenous { static bool const yes = false; };

    template< class T >
    struct IsHomogenous< T, T, T > { static bool const yes = true; };
}  // namespace detail

template< class T1, class T2, class T3 >
bool isHomogenous( Blah< T1, T2, T3 > )
{
    return detail::IsHomogenous< T1, T2, T3 >::yes;
}

#include <iostream>
int main()
{
    using namespace std;
    wcout << boolalpha
        << isHomogenous( Blah< double, char, void >() ) << " "
        << isHomogenous( Blah< int, int, int >() )
        << endl;
}

もう1つの方法は、C++11を使用することですstd::is_same

#include <type_traits>

template< class T1, class T2, class T3 >
struct Blah {};

template< class T1, class T2, class T3 >
bool isHomogenous( Blah< T1, T2, T3 > )
{
    using std::is_same;
    return is_same< T1, T2 >::value && is_same< T2, T3 >::value;
}

#include <iostream>
int main()
{
    using namespace std;
    wcout << boolalpha
        << isHomogenous( Blah< double, char, void >() ) << " "
        << isHomogenous( Blah< int, int, int >() )
        << endl;
}
于 2012-10-15T10:15:17.757 に答える
2

テンプレート関数を特殊化することはできません。特殊化を追加すると、特殊化された関数が実際にオーバーロードセットに追加されるため、オーバーロードと同じになり、オーバーロード解決ルールを呼び出す関数を選択するために使用されます。

テンプレート関数を本当に特殊化したい場合は、静的メンバーを持つ構造体またはクラスに委任し、代わりにテンプレート構造体を特殊化します。

template <typename T>
struct handler
{
   static void perform(T& );
};

template <>
struct handler<int>
{
   static void perform(int) { doStuff(); }
};

そして、これがグローバル関数(あなたが専門にしたい)です:

template <typename T>
void function (T& v)
{
   handler<T>::perform(v);
}

お役に立てれば。

于 2012-10-15T10:15:28.013 に答える
0

trueまたはfalseを返すファンクターを使用してクラスを部分的に特殊化することができます。(または静的メンバー、何でも):

template< class T1, class T2, class T3 >
class Blah {};

template< class T>
struct isHomogenous
{
    const bool operator()() { return false; }
};

template< template <typename,typename,typename> class T, class T1, class T2, class T3 >
struct isHomogenous<T<T1,T2,T3>>
{
    const bool operator()() { return false; }
};



template< template <typename,typename,typename> class T, class T1>
struct isHomogenous<T<T1,T1,T1>>
{
    const bool operator()() { return true; }
};

std::cout << isHomogenous< Blah<double, char, void> >()() << " "
    << isHomogenous< Blah<int, int, int> >()();
于 2012-10-15T10:33:19.173 に答える