我需要什么:
template <class Context/*if Context has a Buffer typedef*/>
struct Buffer {
typedef typename Context::Buffer type;
};
template <class Context/*if Context doesn't have a Buffer typedef*/>
struct Buffer {
typedef std::shared_ptr<void> type;
};
如果参数类Context具有Buffer typedef,则使用它,否则将使用shared_ptr。
如何编写模板?提前谢谢。
答案 0 :(得分:1)
对SFINAE使用部分类模板特化。它甚至适用于C ++ 11。
struct A
{
using tag = void;
static constexpr const char *name = "A";
};
struct B
{
static constexpr const char *name = "B";
};
template <typename T> struct S
{
static void func()
{
std::cout << T::name << " - no tag\n";
};
};
template <typename T, typename = typename T::tag> using enable_if_has_tag = T;
template <typename T> struct S<enable_if_has_tag<T>>
{
static void func()
{
std::cout << T::name << " - has tag\n";
};
};
int main()
{
S<A>::func(); // -> `A - has tag`
S<B>::func(); // -> `B - no tag`
}
答案 1 :(得分:1)
使用void_t
帮助程序非常简单:
#include <memory>
#include <type_traits>
template <typename...> using void_t = void;
template <class Context,class = void>
struct Buffer {
typedef std::shared_ptr<void> type;
};
template <class Context>
struct Buffer<Context,void_t<typename Context::Buffer> > {
typedef typename Context::Buffer type;
};
int main()
{
struct Context1 {
};
struct Context2 {
typedef int Buffer;
};
{
using A = Buffer<Context1>::type;
using B = std::shared_ptr<void>;
static_assert(std::is_same<A,B>::value,"");
}
{
using A = Buffer<Context2>::type;
using B = int;
static_assert(std::is_same<A,B>::value,"");
}
}
请注意std::void_t
在C ++ 17中,但很容易创建自己的。