There are three ways to solve your problem: one of them will be the implementation of is_specialization_of , the second is to force your function to accept std::basic_string<T1,T2,T3> instead of TString , and the third has the same philosophy as the second solution; make the template suitable only for std::basic_string .
is_base_of not enough in your example due to two reasons:
is_base_of used to find out if type U not derived from T (or if it is of the same type), there is no inheritance in your fragment.
std::basic_string not a full type and therefore cannot be used with is_base_of at all (as you already mentioned).
solution # 1
is_specialization_of will be used to check if type U specialization of an incomplete type T This is pretty easy to implement with a template, as in the example below.
as noted by @SebastianRedl variation patterns, are not available using VS2012, see other solutions (which are not common, but still sufficient for your needs).
#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; }
Output
1 1 0
solution # 2
template <typename T1, typename T2, typename T3> void strings_only_please(std::basic_string<T1,T2,T3>) {
Of course, the above will not lead to a nice static_assert error - but this is enough for your needs and does what you want; a function can only be called by types specializing in std::basic_string .
decision # 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