专门研究非模板类的模板方法 - 在MSVC中工作,在GCC中编译错误

时间:2014-11-04 13:06:54

标签: c++ templates gcc template-specialization

我有一些可以归结为此的代码:

#include <type_traits>

struct CByteArray {};

struct CIODevice {
    template <typename T>
    CIODevice& operator<< (T value)
    {
        static_assert(std::is_pod<T>::value, "This method is only intended for POD types");
        return *this;
    }

    template <>
    CIODevice& operator<< (CByteArray data)
    {
        return *this;
    }

    template <typename T>
    CIODevice& operator>> (T& value)
    {
        static_assert(std::is_pod<T>::value, "This method is only intended for POD types");
        return *this;
    }
};

int main()
{
    CIODevice device;
    int i = 0;
    device << i;
    device >> i;
    return 0;
}

它在MSVC中编译,但在GCC中我得到了这个:

prog.cpp:13:12: error: explicit specialization in non-namespace scope ‘struct CIODevice’
  template <>
            ^
prog.cpp:20:11: error: too many template-parameter-lists
  CIODevice& operator>> (T& value)
           ^
prog.cpp: In function ‘int main()’:
prog.cpp:32:9: error: no match for ‘operator>>’ (operand types are ‘CIODevice’ and ‘int’)
  device >> i;
     ^

Live sample

我不明白,这里的错误是什么?

2 个答案:

答案 0 :(得分:4)

C ++规范§14.7.3(摘录);

  
      
  1. 以下任何一项明确的专业化:...
      
        
    • 类或类模板的成员函数模板...
    •   
  2.   
  3. 应在包含专用模板的命名空间中声明显式特化。
  4.   

基本上,它必须在命名空间范围内声明(如GCC和Clang要求)。

struct CIODevice {
    template <typename T>
    CIODevice& operator<< (T value)
    {
        static_assert(std::is_pod<T>::value, "This method is only intended for POD types");
        return *this;
    }

    template <typename T>
    CIODevice& operator>> (T& value)
    {
        static_assert(std::is_pod<T>::value, "This method is only intended for POD types");
        return *this;
    }
};

template <>
CIODevice& CIODevice::operator<< (CByteArray data)
{
    return *this;
}

Sample code

答案 1 :(得分:1)

另见this

基本上,MSVC是错的,GCC是对的,你做不到。

为什么不使用重载而不是专业化?尝试:

template <typename T>
CIODevice& operator<< (T value)
{
    static_assert(std::is_pod<T>::value, "This method is only intended for POD types");
    return *this;
}

// template <> // <--- Remove this
CIODevice& operator<< (CByteArray data)
{
    return *this;
}