在成员函数的默认参数中使用强类型枚举的成员
Usage of members of a strongly typed enum in a member function's default arguments
我主要使用g++,现在使用Visual Studio 2015。我想用vc++ 2015来构建我的项目,但我得到的错误消息是,在给定默认参数的函数中使用'::'无效,并使用前向声明的强类型enum。
下面是一些代码:struct Foo
{
//! Forward declaration of Bar
enum class Bar : short;
//! "Faulty" function with default argument
void DoSmth(Bar aBar = Bar::Baz)
{
// ... code ...
}
//! Complete declaration of Bar
enum class Bar : short
{
Baz
};
};
int main() { }
在使用默认参数Bar::Baz:
声明函数DoSmth()时出现以下错误test.cpp(7): error C2589: '::': illegal token on right side of '::'
test.cpp(7): error C2059: syntax error: '::'
test.cpp(17): fatal error C1903: unable to recover from previous error(s); stopping compilation
使用g++(在4.9和5.1下测试),代码编译得很好,但使用vc++ 2015就不行了。
我完全意识到我必须在使用but之前声明一些东西。仅仅是因为vc++ 2015没有在类的范围内查找Bar的完整声明和定义,但g++却这样做了吗?或者,也许c++只是采取完整的声明,并将其与前向声明"合并"(因为它们在相同的作用域中),从而使其对类完全可用?或者我只是错了,是完全不同的原因导致了这一切?
我可以忍受,为了使它在vc++ 2015中工作,我必须更改所有强类型枚举的声明。
但我也想知道这是为什么?
你的代码是有效的,vc14拒绝它是错误的。
根据N4527,现行标准工作草案,[9.2p2]:
类被认为是完全定义的对象类型(3.9)(或完整类型)在类说明符的结束
}
处。在类成员规范,类被认为是完整的函数体,默认参数,using-declarations introducing继承构造函数(12.9)、异常规范和大括号或相等初始化式非静态数据成员(包括这些东西在嵌套类中)。否则就被认为是不完整的在它自己的类成员规范中。
在默认参数中,查找Bar::Baz
需要Bar
的完整定义,这在完整的类中可用,所以一切都很好。
也许现在的解决方法是将enum class
的完整定义移动到DoSmith()
的函数调用之前。
相关文章:
- c++类声明时,相同的例程,不同的成员变量类型
- 是否可以根据其数据成员的类型确定类型的大小
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 无法推断模板化类成员的类型
- static_assert私有类成员的类型,没有实例
- 在运行时选择类成员的类型
- 是否可以确定枚举是否为强类型?
- 继承类中的 C++ 成员变量类型重写
- 在编译时将强类型枚举器转换为其基础类型?
- 拒绝包含某些公共静态数据成员的类型
- 如何进行编译时type_check并且仅在类成员的类型与类型匹配时才编译类的一部分?
- 如何在不创建实例的情况下获取类的方法成员的类型?
- 类成员的类型定义
- 如何根据参数化类型的特定成员的类型对模板类函数进行不同的实现
- 如果 int 是"not within the enums range",为什么将 int 转换为强类型枚举会编译?
- 具有依赖于实现的成员函数类型的多个静态接口
- 位字段成员的类型
- 原始类型的强类型(BOOST_STRONG_TYPEDEF没有切割)
- 根据参数设置构造函数的成员数据类型
- 在成员函数的默认参数中使用强类型枚举的成员