【问题标题】:Compilation errors when attempting to use SFINAE (std::enable_if) and template specialization尝试使用 SFINAE (std::enable_if) 和模板特化时出现编译错误
【发布时间】:2014-11-03 13:38:38
【问题描述】:

考虑代码:

#include <type_traits>

struct CByteArray {};
struct HLVariant {
    HLVariant() {}
    HLVariant(const HLVariant&) {}
    HLVariant(const CByteArray&) {}

    };

template <typename T>
inline CByteArray serialize(const typename std::enable_if<true, T>::type& value)
{
    return serialize(HLVariant(value));
}

template <typename T>
inline CByteArray serialize(const typename std::enable_if<false, T>::type& value)
{
    return CByteArray();
}

template <>
inline CByteArray serialize(const HLVariant& value)
{
    return CByteArray();
}

int main()
{
    serialize(0);
    serialize(CByteArray());
    serialize(HLVariant());

    return 0;
}

Microsoft Visual Studio 2013 给出以下错误:

C2912:显式特化 'CByteArray serialize(const HLVariant &)' 不是函数模板的特化

错误 C2783:'CByteArray 序列化(常量 std::enable_if::type &)' : 无法推断出 'T' 的模板参数

错误表明编译器看不到template &lt;typename T&gt; CByteArray serialize(const T&amp;); 函数,我不明白为什么。请注意,我只是将truefalse 用于enable_if 条件,用于此处的测试目的。

我也尝试过这种方式(enable_if 返回类型而不是参数):

    template <typename T>
inline typename std::enable_if<true, CByteArray>::type serialize(const T& value)
{
    return serialize(HLVariant(value));
}

template <typename T>
inline typename std::enable_if<false, CByteArray>::type serialize(const T& value)
{
    return CByteArray();
}

现在的错误是:

C2039: 'type' : is not a member of 'std::enable_if<false,CByteArray>'

【问题讨论】:

  • 我想如果你用结构专业化来做它会起作用的......(正在努力)
  • 对于 SFINAE,条件应取决于模板参数。
  • template &lt;&gt; inline CByteArray serialize(const HLVariant&amp; value) 由于您没有明确指定模板参数,编译器将不得不推断它们(从函数参数类型)。但这是不可能的,因为对于两个 serialize 模板,T 处于非推断上下文中。
  • std::enable_if&lt;false, CByteArray&gt;::type 由于没有依赖于模板参数的类型,所以这里没有进行替换,因此替换时不会发生错误(=> 硬错误,没有 SFINAE)。

标签: c++ templates sfinae


【解决方案1】:

typename std::enable_if&lt;true, T&gt;::type 在您的上下文中不可扣除(T 应该编译器测试,对于一般情况,它可能是无限类型)。

你可以改用:

template <typename T>
inline
typename std::enable_if</*your condition depending of T*/, CByteArray>::type
serialize(const T& value)
{
    // Your code
}

【讨论】:

  • true/false 不依赖于T,所以你有一个硬错误,而不是替换失败。
  • 我明白了!快到了,但还没有。现在它用 ideone 编译,但 MSVC 仍然给出错误'type' : is not a member of any direct or indirect base class of 'std::enable_if&lt;false,CByteArray&gt;'。代码见这里:ideone.com/WTaWpD
猜你喜欢
  • 1970-01-01
  • 2015-10-17
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
相关资源
最近更新 更多