一個可行的方法就是利用這一點:
別名模板永遠不會被模板參數推導得出推斷模板的模板時參數。
http://en.cppreference.com/w/cpp/language/type_alias
因此,與類型特徵像
template<
typename T,
template<typename...> class Template
>
struct instantiated_from
: std::false_type {};
template<
template<typename...> class Template,
typename... Arguments
>
struct instantiated_from<Template<Arguments...>, Template>
: std::true_type {};
我們可以肯定的是,當我們通過Alias<int>
作爲第一個模板參數和Alias
爲第二,那麼編譯器不會選擇專業化。這立即給我們:
template<
template<typename...> class Template,
typename... Args
>
struct is_alias_template
: std::integral_constant<
bool,
! instantiated_from<Template<Args...>, Template>::value
>
{};
有了這個,我們可以 - 給出一些合適的模板參數 - 檢測模板是否爲別名模板或不:
int main() {
static_assert( is_alias_template<Alias, int>::value, "");
static_assert(! is_alias_template<Normal, int>::value, "");
static_assert( is_alias_template<Alias, Alias<int>>::value, "");
static_assert( is_alias_template<Alias, Normal<int>>::value, "");
static_assert(! is_alias_template<Normal, Alias<int>>::value, "");
static_assert(! is_alias_template<Normal, Normal<int>>::value, "");
}
這裏的主要缺點是當然的那個人需要知道一組合適的模板參數。只是猜測(或使用int
)將不適用於具有固定號碼(> 1)模板參數的模板。
此外,這不適用於具有非類型(或模板)模板參數的模板(別名或不模板)。