MSVC:非成员函数上不允许使用修饰符
MSVC: modifiers not allowed on non-memberfunction
我在linux下写了一个Signal/Slot库(Codeproject文章),使用Clang 3.5和GCC4.9进行编译。它在两个编译器(也在版本 3.4 resp 4.8)上编译时没有警告。当我让它全部工作并在网上发布文章时,不久我就收到了关于它在 MSVC 上不起作用的投诉。(Visual Studio Express 2013?对不起,我不熟悉版本控制系统。我将其安装在 VM 中以亲自查看,发现它不会编译以下内容:
template <typename Signature>
struct RemoveCV;
template <typename R, typename ... Args>
struct RemoveCV<T, R (Args...)>
{
using Type = R(Args...);
};
template <typename R, typename ... Args>
struct RemoveCV<T, R(Args...) const>
{
using Type = R(Args...);
};
// more specializations for volatile and const volatile
// Usage:
template <typename Signature_>
struct Function
{
using Signature = RemoveCV<Signature_>::Type;
};
// both Function<void()> and Function<void() const> now have
// the same Signature: void()
原因是R(Args ...)
不是成员函数,因此它不能具有const
限定符。
虽然在非成员函数上有一个const
限定符当然是没有意义的,但我相信我在某处读到过(这里关于 SO,包括标准的引用),只要它不绑定到实际函数,它就是允许的。 即允许它作为独立类型。不幸的是,我似乎再也找不到那个线程了......
我只是想知道在这种情况下谁是对的:MSVC 或 GCC + Clang,以及标准对像 void() const
这样的独立函数签名有什么看法。
好吧,我相信您(以及 GCC 和 Clang)似乎是对的,关于标准所说的内容。从 §8.3.5/6(在 N3376 中),(强调我的):
简历限定符序列或参考限定符只能是以下部分的一部分:
— 非静态成员函数的函数类型,
— 指向成员的指针所引用的函数类型,
— 函数 typedef 声明或别名声明的顶级函数类型,
— 类型参数(14.1) 的默认参数中的类型 ID,或
— 类型参数的模板参数的类型 ID (14.2)。
相关文章:
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 不允许运算符 const 参数调用 const 成员函数
- 为什么C++不允许我在类中使用字符串作为数据成员?
- 为什么不允许静态成员变量的初始化在类中,而允许静态静态成员的初始化
- 仅允许访问对象的成员,而不允许访问对象本身
- C++ 成员声明中不允许使用限定名称
- C++不允许我在公共函数中使用私有成员变量
- 为什么私有继承对象允许成员函数将派生的*转换为基*,而外部不能
- C++ 错误 - <unnamed-tag>不允许匿名联合的成员使用 cass 内初始值设定项
- 为什么不允许对成员函数的模板专业化
- G++ 不允许我定义名为 "major" 的成员函数
- 为什么C++继承不允许基类的公共成员继承到派生类的私有成员?
- 不允许继承成员,为什么
- 为什么不允许将右值引用绑定到非常数引用,而允许在其中一个上调用非常数成员函数
- 为什么在构造函数之外不允许初始化类成员
- 错误 C2761 不允许成员函数重新声明
- 不允许使用C++数据成员初始值设定项
- 为什么不允许在类中专用化成员函数模板
- 为什么不允许对成员函数的内联定义进行额外的限定
- 不允许成员函数的非指针类型定义