MSVC:非成员函数上不允许使用修饰符

MSVC: modifiers not allowed on non-memberfunction

本文关键字:不允许 成员 函数 MSVC      更新时间:2023-10-16

我在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)。