:あなたはコンストラクタを専門にしたい場合はhttp://en.cppreference.com/w/cpp/language/template_specialization
EDIT
:ここ
は、リンクです私があなたの質問を編集した後に私が信じているのは、それぞれの実装がSFINAEで動作するパラメータタイプを決めることができます。
duo(const T& value);
duo(const std::string& name);
我々は今、時代に同じシグネチャを持っているので、これはTがstd::string
である場合には失敗します。問題はOPの質問に与えられたとして、我々は次のようにコンストラクタの2つのバージョンを書いた場合は何
テンプレートがT = std :: stringにインスタンシエートするので、シグネチャの2倍の時間が得られます。duo(const std::string& name);
SFINAEは、テンプレートを初期化できないため、インスタンス化で「不可視」です。したがって、達成したいこと:
duo(const T& value);
このシグネチャは、コンストラクタのパラメータがクラスが作成されたものと同じである場合には常に取られます。したがって、Tがintで、入力パラメータがintの場合、このバージョンを使用する必要があります。これはで達成することができます:
template <typename X, typename std::enable_if< std::is_same<T,X>::value,
int>::type* = nullptr >
duo(const X& value): VALUE(value);
しかし、我々は、入力としてstd::string
を持っている場合、我々は、変換コンストラクタを使用します。 しかし、Tがstd::string
である特別なケースがあり、変換の必要がないため、このコンバージョンコンストラクタを使用したくないことに注意してください。だから我々はまた、上記のバージョンが欲しい。だからSFINAEを使ってそのバージョンを作るのは、Tがstd::string
ではない場合にのみ有効です!試験した全ての例で
template <typename X=T, typename
std::enable_if<!std::is_same<X,std::string>::value, int>::type*
= nullptr >
duo(const std::string& name);
完全な作業例:
template< class T >
class duo
{
private:
T VALUE;
std::string NAME;
public:
// Templated version
template <typename X, typename std::enable_if< std::is_same<T,X>::value, int>::type* = nullptr >
duo(const X& value): VALUE(value)
{
std::cout << "Templated version" << std::endl;
std::cout << __PRETTY_FUNCTION__ << value << std::endl;
}
// Normal version
// should NOT work if type is std::string, because in this case version above is simplier!
template <typename X=T, typename std::enable_if<!std::is_same<X,std::string>::value, int>::type* = nullptr >
duo(const std::string& name)
{
std::cout << "Normal version" << std::endl;
std::cout << __PRETTY_FUNCTION__ << name << std::endl;
std::istringstream is(name);
is >> VALUE;
}
T GetVal()
{
return VALUE;
}
};
int main()
{
duo<int> int1(1);
duo<int> int2("123");
duo<double> double1(1.234);
duo<double> double2("9.876");
duo<std::string> string1(std::string("Hallo"));
std::cout << int1.GetVal() << std::endl;
std::cout << int2.GetVal() << std::endl;
std::cout << double1.GetVal() << std::endl;
std::cout << double2.GetVal() << std::endl;
std::cout << string1.GetVal() << std::endl;
}
SFINAEは11が、std::enable_if
とstd::is_same
は、あなたの自己によって書かれた、あるいは単にSTLからコピーする必要があり、C++なしでも動作します。
テンプレートの任意の種類のインスタンスを使用する場合は、テンプレートが記述する「もの」のインスタンスを取得:あなたのコメントに答えるために
。テンプレートクラスの新しいテンプレートインスタンスは、そのインスタンスの新しいコードを生成します。テンプレートコンストラクタでも同じです。しかし、オーバーヘッドは手作業でコードを書くのと同じです。 SFINAEはオーバーヘッドを発生させません!すべてのアクションはコンパイル時に実行されます。
あなたの要件を例で説明できますか? – shafeeq
なぜ両方のコンストラクタを作成しないのですか? 'duo(const std :: string&name、const T&value);' – Rene
私はさらに明確にするために私の質問を編集しました@Rene –