2017-02-07 15 views
7

与えられた型に対して、他の型から派生したものであれば何か他のものから派生している場合、他のすべての場合には何か他のことをするという問題があります。私のコード:BaseClassに基づいて、クラスDeriviedClass及びその他についてはstd :: is_base_ofを持つ派生クラスのC++テンプレート関数

class BaseClass {}; 
class DerivedClass : public BaseClass {}; 

template <typename T> 
void Function(typename std::enable_if<std::is_base_of<BaseClass, T>::value, T>::type && arg) { 
    std::cout << "Proper"; 
} 

template <typename T> 
void Function(T && arg) { 
    std::cout << "Improper"; 
} 

void test() { 
    Function(DerivedClass{}); 
} 

私はProperをcouting機能を呼びたいが、それcoutsImproperと思います。助言がありますか?

+2

Tは、結果の型にenable_if移動し、ここでは非推測コンテキストにある: 'オート機能(T) - >型名enable_if :: type'が。 –

答えて

6

SFINAEの表現は、あなたが行ったようには動作しません。
それは、代わりにこのようなものでなければなりません:

template <typename T> 
typename std::enable_if<std::is_base_of<BaseClass, T>::value>::type 
Function(T && arg) { 
    std::cout << "Proper" << std::endl; 
} 

template <typename T> 
typename std::enable_if<not std::is_base_of<BaseClass, T>::value>::type 
Function(T && arg) { 
    std::cout << "Improper" << std::endl; 
} 

SFINAE式はBaseClassTのベースであるという事実に依存Functionを有効または無効にします。どちらの場合でも戻り値の型はvoidです。定義していない場合は、std::enable_itの既定の型です。
coliruでご覧ください。

他の有効な代替方法が存在し、その一部は他の回答に記載されています。

+1

特定のタイプの関数をオーバーロードする可能性はありますか?浮く? – miqelm

+1

@miqelmオーバーロードされたテンプレート以外の関数がテンプレートよりも優先されます(例:[here](http://coliru.stacked-crooked.com/a/b49a7e7f56954978)を参照)。 – skypjack

3
template <typename T> 
auto Function(T && arg) -> typename std::enable_if<std::is_base_of<BaseClass, T>::value>::type 
{ 
    std::cout << "Proper"; 
} 

template <typename T> 
auto Function(T && arg) -> typename std::enable_if<!std::is_base_of<BaseClass, T>::value>::type 
{ 
    std::cout << "Improper"; 
} 

​​3210

3
#include <typeinfo> 
#include <iostream> 

class BaseClass {}; 
class DerivedClass : public BaseClass {}; 
class OtherClass {}; 

template <typename T,typename = typename std::enable_if<std::is_base_of<BaseClass, T>::value, T>::type> 
void Function(T && arg) 
{ 
    std::cout << "Proper" << std::endl; 
} 

void Function(...) 
{ 
    std::cout << "Improper"<< std::endl; 
} 

int main() 
{ 
    Function(DerivedClass{}); 
    Function(BaseClass{}); 
    Function(OtherClass{}); 
} 
+0

'Function (OtherClass {});'は簡単に分割するために使用できます。溶液が少なすぎます。 – skypjack

関連する問題