c++ - 覆盖说明符作为模板参数 - 它有效吗?

标签 c++ c++11 compiler-bug

我有以下代码在 Visual C++ 2015 下无法编译,但在 GCC 4.8.4 下可以编译。我想知道哪个是正确的?有问题的代码如下:

template <class T> class ATemplate;
template <class R, class A1>
    struct ATemplate<R(A1)>{ };

int main()
{
    ATemplate<void(int)> x;
//    ATemplate<void(int)override> y; //---Does not compile!!!
    return 0;
}

在下面使用 override 作为说明符(或 const)是否错误。 GMock库中也有类似的代码,其中宏扩展用于生成模板参数(包括覆盖),以及实际的函数签名。

Visual C++ 2015 在删除注释掉的行时会产生以下错误:

x.cpp(11): error C2062: type 'int' unexpected
x.cpp(11): error C2976: 'ATemplate': too few template arguments
x.cpp(4): note: see declaration of 'ATemplate'
x.cpp(11): error C2079: 'y' uses undefined class 'ATemplate'

下面的答案之一提到 override 在自由函数的上下文中没有意义(有效点) - 这是否意味着 GCC 在这里是错误的。 const 说明符 在这种情况下也没有意义(对于自由函数),但仍然允许(VC++)???此外,它提到虚拟说明符应该只存在于声明中 - 这对这种情况没有影响(因为不存在定义)。对于 virtual 关键字,在派生中省略是可以的,因为它对代码是否编译没有影响,但对于覆盖情况,它就不行,因为它有很大的不同。

当使用 ReturnType (ArgType arg) ...possible const or override specifier 作为宏参数(就像 GMock 一样)时,VCC 施加的限制导致此代码无法编译(显然是这种情况也适用于 Clang)。哪个是对的?

该标准没有规定不应在此上下文中使用覆盖说明符(模板参数的上下文?),是吗?

最佳答案

这是一个 g++ 错误。

标准允许 virt-specifier-sec 在两个产生式中:在函数定义中(仅适用于 virtual member-function 定义)并在一个成员声明器中。你的上下文既不是。

GCC 错误行为的简短演示:

void foo(void) override;          // g++ rejects with message: 
                                  //  virt-specifiers in 'foo' 
                                  //  not allowed outside a class definition
void (*bar)(void) override;       // g++ erroneously accepts
typedef void baz(void) override;  // g++ erroneously accepts

关于c++ - 覆盖说明符作为模板参数 - 它有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33474041/

相关文章:

c++11 - std::getline 和 UTF16 (LE) 文件流 - 不工作

c++ - lambda 如何在 MSVC2017 15.9.3 with/std :c++17? 中使用静态本地错误返回值

c++ - 转换后是右值还是左值

c++ - 在项目的另一个类中使用 QTimer 及其超时事件

c++ - 可由设备或主机调用的 CUDA 函数

c++ - 同时等待套接字和 bool var 的可移植 C++11 方法

c++ - Visual C++ 编译和生成巨大目标文件的嵌套 lambda 表达式非常慢

c++ - 反向迭代流

c++ - 一个简单的 boost.spirit 示例中的 error_invalid_expression 编译错误

c++ - std::remove_extent 有什么用?