如果类型"T"具有"模板<>结构编写器<T>"来序列化自身



我有一个Writer结构体来做一些序列化

template<typename T>
struct Writer {};  // only specialized version has ::wrap_t
template<>
struct Writer <int> {
typedef int wrap_t;
};
template <typename T>
using Writer_wrap_t = typename Writer<T>::wrap_t;
template<>
struct Writer<float> {
typedef float wrap_t;
};

我想知道一个类型是否有专门的Writer。代码没有按预期工作:

template<typename T, typename U = Writer_wrap_t <T>>
struct has_writer : std::true_type {};
template<typename T>
struct has_writer<T, void> : std::false_type {};
int main() {
bool b = has_writer <double>::value;
// error C2794: 'wrap_t': is not a member of any direct or indirect base class of 'Writer<T>'
// error C2976: 'has_reflect': too few template arguments
// error C2938: 'Writer_wrap_t ' : Failed to specialize alias template
}

我猜想has_writer<double>没有使用专用版本struct has_writer<T, void> : std::false_type {};?

但是现在第一个版本的替换失败了,编译器不应该尝试实例化第二个版本吗?

您没有正确使用SFINAE。典型的模式是定义一个主模板,其中第二个模板参数是void

template<typename T, typename = void>
struct has_writer : std::false_type {};

,然后使用您想要检查的任何类型的std::void_t作为第二个参数

对模板进行专门化
template<typename T>
struct has_writer<T, std::void_t<Writer_wrap_t <T>>> : std::true_type {};

如果传递给void_t的类型是格式良好的,则选择专门化,这是真情况,否则选择主类型,这是假情况。Writer_wrap_t本身只有在传递给它的类型有一个成员类型为pedefwrap_t时才是格式良好的。