我有一些可以归结为此的代码:
#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;
^
我不明白,这里的错误是什么?
答案 0 :(得分:4)
C ++规范§14.7.3(摘录);
- 以下任何一项明确的专业化:...
- 类或类模板的成员函数模板...
- 应在包含专用模板的命名空间中声明显式特化。
醇>
基本上,它必须在命名空间范围内声明(如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;
}
答案 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;
}