我正在尝试使用模板和 SFINAE 来做一些事情,我是其中的初学者。我正在浪费大量时间来完成每件最简单的事情。你能帮我理解它是如何工作的吗?
C< T , Ts... > 的构造函数采用 A< U > 或 B< U > 的 T 参数,但在这两种情况下具有不同的行为。我无法向你展示我试图这样做的一切。这是在我看来最不愚蠢的方式。
template<typename T> class A{
public: A(){} };
template<typename T> class B{
public: B(){} };
template<typename T> struct enable_if_A {};
template<typename T> struct enable_if_A< A<T> > {typedef A<T> type;};
template<typename T> struct enable_if_B {};
template<typename T> struct enable_if_B< B<T> > {typedef B<T> type;};
template<typename T,typename... Ts> class C{
public:
C(typename enable_if_A<T>::type const &p){cout << "A" << endl;}
C(typename enable_if_B<T>::type const &p){cout << "B" << endl;}
};
// ...
A<float> a;
B<float> b;
C<A<float> > ca(a); // error: no type named ‘type’ in ‘struct enable_if_B<A<float> >'
C<B<float> > cb(b); // error: no type named ‘type’ in ‘struct enable_if_A<B<float> >'
注意:我使用的是 g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1。我应该升级它吗?
谢谢
编辑:有关更多详细信息,我还尝试了(除其他外):
template<typename T,typename... Ts> class C{
public:
template<>
C(typename enable_if_A<T>::type const &p){cout << "A" << endl;}
template<>
C(typename enable_if_B<T>::type const &p){cout << "B" << endl;}
};
//explicit specialization in non-namespace scope ‘class bcifs::C<T, Ts>’
//////////////////////////////////////////////////////////////////////////
template<typename T,typename... Ts> class C{
public:
template<typename E=void>
C(typename enable_if_A<T>::type const &p){cout << "A" << endl;}
template<typename E=void>
C(typename enable_if_B<T>::type const &p){cout << "B" << endl;}
};
// error: no type named ‘type’ in ‘struct enable_if_B<A<float> >'
//////////////////////////////////////////////////////////////////////////
template<typename T> struct enable_if_A {};
template<typename T> struct enable_if_A< A<T> > {typedef void type;};
template<typename T> struct enable_if_B {};
template<typename T> struct enable_if_B< B<T> > {typedef void type;};
template<typename T,typename... Ts> class C{
public:
template<typename E=void>
C(T const &p);
C<typename enable_if_A<T>::type>(T const &p){cout << "A" << endl;}
C<typename enable_if_B<T>::type>(T const &p){cout << "B" << endl;}
};
// error: invalid declarator before ‘(’ token
//////////////////////////////////////////////////////////////////////////
template<typename T> class C{
public:
template<>
C(T const &p,typename enable_if_A<T>::type * = 0){cout << "A" << endl;}
template<>
C(T const &p,typename enable_if_B<T>::type * = 0){cout << "B" << endl;}
};
// error: explicit specialization in non-namespace scope ‘class C<T>’
// error: no type named ‘type’ in ‘struct enable_if_B<A<float> >’
//////////////////////////////////////////////////////////////////////////
template<typename T> class C{
public:
template<typename U>
C(T const &p,typename enable_if_A<T>::type * = 0){cout << "A" << endl;}
template<typename U>
C(T const &p,typename enable_if_B<T>::type * = 0){cout << "B" << endl;}
};
// error: no type named ‘type’ in ‘struct enable_if_B<A<float> >’
// error: no matching function for call to ‘C<A<float> >::C(A<float>&)’
//////////////////////////////////////////////////////////////////////////
template<typename T> struct enable_if_A {};
template<typename T> struct enable_if_A< A<T> > {typedef void type;};
template<typename T> struct enable_if_B {};
template<typename T> struct enable_if_B< B<T> > {typedef void type;};
template<typename T> class C{
public:
template <typename U>
C(A<U> const & r, void* _ = 0);
};
template <typename T>
template <typename U>
C<T>::C<T>(A<U> const & r, typename enable_if_A<U>::type* _ = 0) {
cout << "A" << endl;
}
// error: ISO C++ forbids declaration of ‘C’ with no type [-fpermissive]
// error: function template partial specialization ‘C<T>’ is not allowed
// error: no ‘int C<T>::C(const A<U>&, typename enable_if_A<U>::type*)’ member function declared in class ‘C<T>’
// C<T>::C<U>(... does the same
很抱歉,但我从未设法运行您的解决方案。我终于发现:
// dummy-function-parameter-ed version :
template<typename T> class C{
public:
template <typename U>
C(A<U> const &r,typename enable_if<is_same<A<U>,T>::value>::type* = 0){cout << "A" << endl;}
template <typename U>
C(B<U> const &r,typename enable_if<is_same<B<U>,T>::value>::type* = 0){cout << "B" << endl;}
};
// and the dummy-template-parameter-ed version :
template<typename T> class C{
public:
template<typename U,typename E = typename enable_if<is_same<A<U>,T>::value>::type>
C(A<U> &r){cout << "A" << endl;}
template<typename U,typename E = typename enable_if<is_same<B<U>,T>::value>::type>
C(B<U> &r){cout << "B" << endl;}
};