Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用std::enable_if on模板函数返回类型利用SFINAE编译错误_C++_Templates_Sfinae - Fatal编程技术网

C++ 使用std::enable_if on模板函数返回类型利用SFINAE编译错误

C++ 使用std::enable_if on模板函数返回类型利用SFINAE编译错误,c++,templates,sfinae,C++,Templates,Sfinae,下面的代码 #include <type_traits> struct CByteArray {}; struct HLVariant { HLVariant() {} HLVariant(const HLVariant&) {} HLVariant(const CByteArray&) {} }; template <typename T> inline typename std::enable_if<!std

下面的代码

#include <type_traits>

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

    };

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

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

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

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

    return 0;
}
#包括
结构CByteArray{};
结构HLVariant{
HLVariant(){}
HLVariant(const HLVariant&){}
HLVariant(constcbyterarray&){
};
模板
内联类型名称std::enable_if::value,CByteArray>::类型序列化(常量T&value)
{
返回序列化(HLVariant(value));
}
模板
内联typename std::enable_if::type serialize(const T&value)
{
返回cbyteraray();
}
模板
内联CByteArray序列化(常量HLVariant和值)
{
返回cbyteraray();
}
int main()
{
序列化(0);
序列化(CByteArray());
序列化(HLVariant());
返回0;
}
触发编译错误
C2794:“type”:不是MSVC 2013中“std::enable_if”的任何直接或间接基类的成员。但是,它在ideone中确实起作用:

这里怎么了


MSVC 2010、2012和2013中的错误是相同的。

在我看来还可以,但我可以通过从
序列化的最后重载中删除
模板来修复它。没有必要使它成为一个完全专业化的时候,一个正常的超载将做

编辑:其他有效方法是提供仅匹配
HLVariant
(并进一步限制其他专业不再匹配
HLVariant
,以避免歧义)的模板专业化

这应该做到:

#包括
#包括
结构CByteArray{};
结构NonPod{public:inta;private:intb;};
结构HLVariant{
HLVariant(){}
HLVariant(const HLVariant&){}
HLVariant(constcbyterarray&){
HLVariant(const NonPod&){}
};
模板
内联typename std::enable_if::type serialize(const T&value)
{
std::cout::value,CByteArray>::类型序列化(const T&value)
{

我可以打赌错误是“MSVC 2013”吗如果你暗示MS编译器的质量不如GCC,那么你就不能再脱离事实了。@ VioletGiraffe在C++语言的顺应性方面。MS编译器落后于其他领域。它有其他优点,但是不要自欺欺人地说C++语言符合性。MSVC 2013的更新在VS14中是如何工作的?CTP@Yakk:riilight,它不是C++14 compliant还没有。不管怎样,我们能回到主题上来吗?我知道你在那里做了什么…问题是,在我的实际代码中,这样的重载会导致一大堆错误,因为非模板重载优先(IIRC),和
HLvariant
可以通过非显式构造函数从大约50种不同的类型构造。换句话说,将调用
serialize
的错误版本。用户定义的转换应该不如模板精确匹配好?好的,听起来您想要一个只匹配
HLVa的模板专业化riant
(并防止其他专业匹配
HLVariant
,以避免歧义)。我将更新…@BenHymers:是的,这完全正确。我将在将来添加更多专业。因此专业化不起作用,但如果
仍然起作用,则使用
enable\u隐藏?我已经运行了一个简短的检查-它在MSVC中编译。
#include <type_traits>
#include <iostream>

struct CByteArray {};
struct NonPod {public: int a; private: int b;};
struct HLVariant {
    HLVariant() {}
    HLVariant(const HLVariant&) {}
    HLVariant(const CByteArray&) {}
    HLVariant(const NonPod&) {}
};

template <typename T>
inline typename std::enable_if<std::is_same<T, HLVariant>::value && !std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
    std::cout << "serialize non-pod variant\n";
    return CByteArray();
}

template <typename T>
inline typename std::enable_if<!std::is_same<T, HLVariant>::value && !std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
    std::cout << "serialize non-pod non-variant\n";
    return serialize(HLVariant(value));
}

template <typename T>
inline typename std::enable_if<std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
    std::cout << "serialize pod\n";
    return CByteArray();
}

int main()
{
    std::cout << "int:\n";
    serialize(0);
    std::cout << "CByteArray:\n";
    serialize(CByteArray());
    std::cout << "HLVariant:\n";
    serialize(HLVariant());
    std::cout << "NonPod:\n";
    serialize(NonPod());
}