2016-03-19 7 views
4

私は、その引数の型によって異なって動作する関数printを書きたいと思っています。C++ enable_ifにデフォルトの実装ができますか?

template <typename T, typename std::enable_if<std::is_array<T>::value, int>::type = 0> 
void print(const T &v) { 
    std::cout << "array: "; 
    for (const auto &e : v) { 
    std::cout << e << ", "; 
    } 
    std::cout << std::endl; 
} 

template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> 
void print(const T &v) { 
    std::cout << "integral: " << v << std::endl; 
} 

template <typename T, typename std::enable_if<!(std::is_array<T>::value || std::is_integral<T>::value), int>::type = 0> 
void print(const T &v) { 
    std::cout << "default: " << v << std::endl; 
} 

このコードは期待通りに動作しますが、最後の仕様では条件があまりにも複雑である:

は、ここに私の実装です。

最後の方法を簡略化するソリューションはありますか?

+0

あなたはもっと簡単に考えているか分かりません。短い? –

+0

@VaughnCatoはい。大量のケースがある場合、デフォルトの条件節は非常に長くなる可能性があります。 – SaltyEgg

答えて

4

デフォルトの場合に使用できる一般的なアプローチは、可変引数リストを取る関数を持つことです。これは、他の機能が一致しない場合にのみ使用されます。ここでは一例です:唯一の2つのオーバーロードのために

template <typename T, typename std::enable_if<std::is_array<T>::value, int>::type = 0> 
void print_helper(const T &v,int) { 
    std::cout << "array: "; 
    for (const auto &e : v) { 
    std::cout << e << ", "; 
    } 
    std::cout << std::endl; 
} 

template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> 
void print_helper(const T &v,int) { 
    std::cout << "integral: " << v << std::endl; 
} 

template <typename T> 
void print_helper(const T &v,...) { 
    std::cout << "default: " << v << std::endl; 
} 

template <typename T> 
void print(const T &v) 
{ 
    print_helper(v,0); 
} 

、余分な機能はそれだけの価値はないかもしれませんが、あなたはより多くのオーバーロードを取得し、このフォームは本当にデフォルトの場合のために支払うことができます。

+0

これは良い解決策ですが、他のより美しい解決策はありますか? – SaltyEgg

1

私たちが私たちのために、より良いものを作るために余分なチューを使用することができ、Xeoの礼儀:次に

struct otherwise{ otherwise(...){} }; 

template<unsigned I> 
struct choice : choice<I+1>{}; 

// terminate recursive inheritence at a convenient point, 
// large enough to cover all cases 
template<> struct choice<10>{}; 

我々の選択リストの各ランキングは次に好ましいであろう、と私達はちょうど私たちのように無効にする必要があります行く:

私たちの最有力候補が配列である
// just forward to our first choice 
template <class T> void print(const T &v) { print(v, choice<0>{}); } 

template <class T, class = std::enable_if_t<std::is_array<T>::value>> 
void print(const T& v, choice<0>) { ... } 

アンその後、一体型D:

template <class T, class = std::enable_if_t<std::is_integral<T>::value>> 
void print(const T& v, choice<1>) { ... } 

そして何が

template <class T> 
void print(const T& v, otherwise) { ... } 

この構造は、任意に多くの選択肢が可能になります。

関連する問題