2017-06-30 2 views
2

ここに私の最初の試みだ -は、特定の列挙値に関数パラメータを制限

私は allowLeftOnly機能から何をしたいです
#include <iostream> 
using namespace std; 

enum class props { 
    left, right 
}; 

template<typename T> 
auto allowLeftOnly(T p) -> decltype((p==props::left), void()) 
{ 
    cout << "Wow!"; 
} 

int main() { 
    props p1 = props::left; 
    props p2 = props::right; 
    allowLeftOnly(p1); 
    // allowLeftOnly(p2); // should fail to compile 
} 

だけprops::leftか、私は明示的にパラメータとして指定し、他の人のためにコンパイルに失敗他人を受け入れることですが。それは可能ですか?

+2

'p'は、あなたがしたいことをするためのテンプレートパラメータにする必要があります。 – Simple

+4

このソリューションで解決したい*実際の問題は何ですか? *なぜ*あなたはこれをしたいですか? [XY問題](http://xyproblem.info/)を読んで質問がどのようにその例であるかを考えてください。 –

+0

@Someprogrammerdude実質的な何かを解決しようとしていない、C++のTMP側を学ぼうとする –

答えて

4

いいえ、できません。 p1p2の値はコンパイル時のプロパティではなく、実行時プロパティであるため、コンパイラはコンパイル時にその値を「認識」しません。

あなたは彼らがconstexprを使用してコンパイル時に知らしめ、その代わりにテンプレート引数として渡す、などができます。

#include <iostream> 
#include <type_traits> 

enum class props { 
    left, right 
}; 

template <props v> 
typename std::enable_if<v == props::left, void>::type allowLeftOnly() 
{ std::cout << "Wow!\n"; } 

int main() { 
    constexpr auto p1 = props::left; 
    constexpr auto p2 = props::right; 
    allowLeftOnly<p1>(); 
    allowLeftOnly<p2>(); // Fails to compile 
} 
3

あなたはテンプレートパラメータにしてpを変更してstd::enable_ifを使用することができ、このように:

template <props p> // p is now a template parameter 
std::enable_if_t<p == props::left> // We only allow p == props::left, return type is implicitly void 
allowLeftOnly() // No 'normal' parameters anymore 
{ 
    std::cout << "Wow!"; 
} 

int main() 
{ 
    constexpr props p1 = props::left; 
    constexpr props p2 = props::right; 
    allowLeftOnly<p1>(); 
    // allowLeftOnly<p2>(); // Fails to compile 
} 
p1については

p2constexprキーワードは、我々はテンプレートパラメータとして変数を使用することができます保証します。

後で別の戻り値の型、例えば、intはその後、使用したい場合:他の回答は、テンプレートパラメータを使用することをお勧めしたように、私もこれを実装する方法を示し答えを追加します

std::enable_if_t<p == props::left, int> 
関連する問題