覆盖说明符作为模板参数 - 它有效吗?
override specifier as template parameter - is it valid?
我有以下代码无法在 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 关键字,在 derived 中省略是可以的,因为它对代码是否编译没有影响,但对于 override 的情况则不行,因为它有很大的不同。
当使用 ReturnType (ArgType arg) ...可能的 const 或覆盖说明符 作为宏参数时(就像 GMock 所做的那样),VCC 施加的限制导致此代码无法编译(显然 Clang 也是如此)。哪个是对的?
标准没有规定覆盖说明符不得在此上下文(模板参数的上下文?)中使用,是吗?
根据标准,override
说明符是上下文相关的并且具有特殊含义仅当它在成员函数之后[=26]使用时=]声明;否则,它不是保留关键字。
所以我想说,你的第二个例子中的代码似乎毫无意义。
我尝试使用 gcc-5.1.0
(使用 -S 标志)编译您的两个示例,它们产生完全相同的程序集。
它无法在 clang-3.7.0
下编译,导致以下错误:
test.cpp:11:23: error: expected '(' for function-style cast or type construction
实际上这意味着您不应该以那种方式使用覆盖。
来自 9.2 Class 个成员(草案 N4140)
virt-specifier-seq:
virt-specifier
virt-specifier-seq virt-specifier
virt-specifier:
override
final
[9.2/8]
A virt-specifier-seq shall contain at most one of each virt-specifier. A virt-specifier-seq shall appear only in
the declaration of a virtual member function (10.3).
据我所知,override
不能应用于自由函数,所以我不希望在自由函数的 signature/type 中允许它(即使它是 const
).
类型的一部分
这是一个 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
我有以下代码无法在 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 关键字,在 derived 中省略是可以的,因为它对代码是否编译没有影响,但对于 override 的情况则不行,因为它有很大的不同。
当使用 ReturnType (ArgType arg) ...可能的 const 或覆盖说明符 作为宏参数时(就像 GMock 所做的那样),VCC 施加的限制导致此代码无法编译(显然 Clang 也是如此)。哪个是对的?
标准没有规定覆盖说明符不得在此上下文(模板参数的上下文?)中使用,是吗?
根据标准,override
说明符是上下文相关的并且具有特殊含义仅当它在成员函数之后[=26]使用时=]声明;否则,它不是保留关键字。
所以我想说,你的第二个例子中的代码似乎毫无意义。
我尝试使用 gcc-5.1.0
(使用 -S 标志)编译您的两个示例,它们产生完全相同的程序集。
它无法在 clang-3.7.0
下编译,导致以下错误:
test.cpp:11:23: error: expected '(' for function-style cast or type construction
实际上这意味着您不应该以那种方式使用覆盖。
来自 9.2 Class 个成员(草案 N4140)
virt-specifier-seq:
virt-specifier
virt-specifier-seq virt-specifier
virt-specifier:
override
final
[9.2/8]
A virt-specifier-seq shall contain at most one of each virt-specifier. A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).
据我所知,override
不能应用于自由函数,所以我不希望在自由函数的 signature/type 中允许它(即使它是 const
).
这是一个 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