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

时间:2015-01-22 10:30:05

标签: c++ c++11

我在linux下编写了一个Signal / Slot库(Codeproject article here),用Clang 3.5和GCC4.9编译。它在两个编译器上都没有警告地编译(也在版本3.4和4.8上)。当我把它全部工作,并在网上发布文章时,不久我得到的投诉是它不能在MSVC上工作。 (Visual Studio Express 2013?对不起,我不熟悉版本控制系统。)我将它安装在虚拟机中以便自己查看,发现它不会编译以下内容:

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这样的独立功能签名的标准。

1 个答案:

答案 0 :(得分:5)

嗯,我相信你(和海湾合作委员会和Clang)似乎是正确的,就标准所说的而言。来自§8.3.5/ 6 (在N3376中),(强调我的):

  

cv-qualifier-seq ref-qualifier 只能属于:

     

- 非静态成员函数的函数类型

     

- 指向成员的指针引用的函数类型,

     

- 函数typedef声明或别名声明的顶级函数类型

     

- type-parameter(14.1)的默认参数中的type-id,或

     

- type-parameter(14.2)的template-argument的type-id。