問題を解決するには 3 つの方法があります。1 つは の実装、もう 1 つはis_specialization_of
関数に のstd::basic_string<T1,T2,T3>
代わりに を使用する方法TString
、3 つ目は 2 番目の解決策と同じ哲学を持ちます。だけでテンプレートをマッチ可能にしstd::basic_string
ます。
is_base_of
次の 2 つの理由から、この例では十分ではありません。
is_base_of
タイプU
が派生してT
いるかどうか(または同じタイプであるかどうか)を確認するために使用されます。スニペットには継承が含まれていません。
std::basic_string
完全なタイプではないため、まったく使用できませんis_base_of
(すでに指摘しました)。
ソリューション #1
is_specialization_of
type が不完全なtypeU
の特殊化であるかどうかを確認するために使用されます。以下の例のように、テンプレート テンプレート クラスを使用して実装するのは非常に簡単です。T
@SebastianRedl で指摘されているように、VS2012 を使用して variadic テンプレートを使用することはできません。他のソリューションを参照してください (一般的ではありませんが、ニーズには十分です)。
#include <type_traits>
#include <iostream>
#include <string>
template<template<typename...> class T, typename U>
struct is_specialization_of : std::false_type { };
template<template<typename...> class T, typename... Ts>
struct is_specialization_of<T, T<Ts...>> : std::true_type { };
int
main (int argc, char *argv[])
{
std::cerr << is_specialization_of<std::basic_string, std::string >::value << std::endl;
std::cerr << is_specialization_of<std::basic_string, std::wstring>::value << std::endl;
std::cerr << is_specialization_of<std::basic_string, std::istream>::value << std::endl;
}
出力
1
1
0
解決策 2
template <typename T1, typename T2, typename T3>
void strings_only_please(std::basic_string<T1,T2,T3>) {
// ...
}
確かに、上記は良いstatic_assert
エラーにはなりませんが、それはあなたのニーズには十分であり、あなたが望むことをします; この関数は、特化した型によってのみ呼び出すことができますstd::basic_string
。
解決策 #3
template<typename T>
struct is_basic_string : std::false_type { };
template<typename T1, typename T2, typename T3>
struct is_basic_string<std::basic_string<T1,T2,T3>> : std::true_type { };
...
is_basic_string<std::string >::value // true
is_basic_string<std::istream>::value // false