テンプレート化された関数を作成しようとしていますが、コンパイル時に特殊化のみを使用するように強制されています。私は、std::false_type
から継承したものにstatic_assert
を使用することを示唆するForce a compile time error in a template specializationを参照しました。デフォルトテンプレートはstatic_assertにもかかわらず一致します
#include <iostream>
using namespace std;
template<typename T>
struct always_false : std::false_type {};
//Case: Default
template<typename T>
void foo(T val) {
static_assert(always_false<T>::value, "");
}
//Case: bool
template<>
void foo<bool>(bool val) {
cout << "Is explicitly a bool! " << val << endl;
}
//Case: int
template<typename T, typename std::enable_if<!std::is_same<T,bool>::value && std::is_convertible<T,int>::value,int>::type=0>
void foo(T val) {
cout << "Can be implicitly converted to int! " << (int)val << endl;
}
int main() {
foo(true); //(Good) Works correctly
foo((int)5); //(Bad) Error: call of overload foo(int) is ambiguous
foo((unsigned int)10); //(Bad) Error: call of overload foo(unsigned int) is ambiguous
foo((void*)nullptr); //(Good) Error: static assertion failed
return 0;
}
私はint
またはunsigned int
に渡すと、コンパイラは呼び出しが、それはCase: Default
またはCase: int
のいずれかを使用することができることを曖昧示唆されていることを訴えます。
Case: Default
にはalways_false
static_assert()
が含まれているので、これは混乱しています。コンパイラはこれを許可しません。
私の最後の例では、void*
を渡すと正常にstatic_assert()
がトリガされ、コンパイル時にエラーが発生します。
私はSFINAEテンプレートメタプログラミングを使用したプログラミングに新しいですので、私は、私はCase: int
専門で何か間違っ
二つの質問やっている疑いがある:
- をなぜ、このコードで
foo(int)
曖昧ですか? - テンプレートを使用して、この望ましい動作(明示的
bool
特殊化+暗黙の整数特殊化)を取得するより良い方法はありますか?
あなたはテンプレートの特殊化、それがでインスタンス化された任意の型に対して有効でなくても、プライマリ1を宣言することはできません。診断は必要ありません。 – StoryTeller