6

何度も特化 (および部分特化) する必要がある特性クラスがあります。

一部の部分的な特殊化は重複しています。

template< typename T > struct C { };
template< typename T1, typename T2 > struct TRAIT { };

template< typename T > struct TRAIT< T, T > { };
template< typename T1, typename T2 > struct TRAIT< C<T1>, C<T2> > { };

int main( ) {
    // ERROR! could be both TRAIT<T,T>   [with T = C<int>]
    //                  and TRAIT<T1,T2> [with T1 = T2 = int]
    TRAIT< C<int>, C<int> > foo;
    return 0;
};

動作するコードで同じ結果を得るにはどうすればよいですか?

私は夢中になりましたenable_ifis_same、もうそれが正しい方法なのかさえわかりません...

4

3 に答える 3

6

専門化の重複を避けることができない場合、これに対する最善の策は、すべての重複を明確にすることです。別の専門分野を作成する必要があります

template< typename T> struct TRAIT< C<T>, C<T> > { };

...しかし、コメントで他の人が言ったように、可能な限り重複を避けるのが最善です. 他の人が指摘したように、問題は専門分野が重複していない可能性があります。これは、問題を解決するための最良のアプローチではない可能性があります。

于 2010-12-06T21:29:37.103 に答える
1

秘訣は、何かが a であるC<Foo>かどうかを示すヘルパー型を作成することです。

template <typename T> struct C {};

template <typename T> struct is_C {
  static bool const value = false;
};
template <typename T> struct is_C<C<T>> {
  static bool const value = true;
};

あなたは正しい軌道に乗ってenable_ifis_sameましたが、行き止まりのようです:

#include <type_traits>

template <typename T1, typename T2, typename Enabled = void> struct Trait {
  static char const test = 'D'; // default
};

template <typename T> struct Trait<
    T,
    T,
    typename std::enable_if<!is_C<T>::value >::type
> {
  static char const test = 'N'; // non-C
};

template <typename T1, typename T2> struct Trait<
    T1,
    T2,
    typename std::enable_if< is_C<T1>::value && is_C<T2>::value >::type
> {
  static char const test = 'C'; // some C
};

今すぐ簡単にテストできます:

#include <iostream>

int main() {
  Trait< C<int>, C<float> > foo1a;
  Trait< C<int>, C<int> > foo1b;
  Trait< int, int > foo2;
  Trait< int, float > foo3;
  std::cout << "Trait<C<int>,C<float>> : " << foo1a.test << std::endl; // prints 'C'
  std::cout << "Trait<C<int>,C<int>> : " << foo1b.test << std::endl; // prints 'C'
  std::cout << "Trait<int,int> : " << foo2.test << std::endl; // prints 'N'
  std::cout << "Trait<int,float> : " << foo3.test << std::endl; // prints 'D'
  return 0;
}

スペシャライゼーションをパラメータの 1 つだけで動作させたい場合は、これを簡単に変更できますC

于 2012-01-07T19:01:49.857 に答える
0

試す:

template< typename T > struct C { };
template< typename T1, typename T2 = T1> struct TRAIT { };
                              // ^^^^^^^^^
                              // Default Type is T1

int main( )
{
        TRAIT<C<int> >         foo1;
        TRAIT<C<int>, C<int> > foo2;

        foo1 = foo2;
        return 0;
};
于 2010-12-06T21:55:40.417 に答える