假设我在模板中,我想知道类型参数T是否是特定模板的实例化,例如std::shared_ptr:
template<typename T>
void f(T&& param)
{
if (instantiation_of(T, std::shared_ptr)) ... // if T is an instantiation of
// std::shared_ptr...
...
}
Run Code Online (Sandbox Code Playgroud)
更有可能我想在std :: enable_if测试中进行这种测试:
template<typename T>
std::enable_if<instantiation_of<T, std::shared_ptr>::type
f(T&& param)
{
...
}
// other overloads of f for when T is not an instantiation of std::shared_ptr
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?请注意,该解决方案需要使用所有可能的类型和模板,包括标准库和我无法修改的其他库中的那些.我对std::shared_ptr上面的使用仅仅是我想要做的一个例子.
如果这是可能的,我将如何自己编写测试,即实现instantiation_of?
ild*_*arn 11
为什么enable_if在简单过载时使用就足够了?
template<typename T>
void f(std::shared_ptr<T> param)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果你确实需要这样的特性,我认为这应该让你开始(只用VC++ 2010进行粗略测试):
#include <type_traits>
template<typename>
struct template_arg;
template<template<typename> class T, typename U>
struct template_arg<T<U>>
{
typedef U type;
};
template<typename T>
struct is_template
{
static T* make();
template<typename U>
static std::true_type check(U*, typename template_arg<U>::type* = nullptr);
static std::false_type check(...);
static bool const value =
std::is_same<std::true_type, decltype(check(make()))>::value;
};
template<
typename T,
template<typename> class,
bool Enable = is_template<T>::value
>
struct specialization_of : std::false_type
{ };
template<typename T, template<typename> class U>
struct specialization_of<T, U, true> :
std::is_same<T, U<typename template_arg<T>::type>>
{ };
Run Code Online (Sandbox Code Playgroud)
部分规范应该能够做到.
template <template <typename...> class X, typename T>
struct instantiation_of : std::false_type {};
template <template <typename...> class X, typename... Y>
struct instantiation_of<X, X<Y...>> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)
我实际上必须查找模板模板语法,因为我基本上没有理由在之前使用它.
不确定这与模板如何std::vector与其他默认参数交互.