我正在编写一个类似于 boost::promote 但适用于 C++11 的升级模板别名。
这样做的目的是避免从变量函数检索参数时出现警告。例如
template <typename T>
std::vector<T> MakeArgVectorV(int aArgCount, va_list aArgList)
{
std::vector<T> args;
while (aArgCount > 0)
{
args.push_back(static_cast<T>(va_arg(aArgList, Promote<T>)));
--aArgCount;
}
return args;
}
升级模板别名会升级遵循可变参数默认参数升级的类型:
1) 小于 int 的整数被提升为 int
2) float 提升为 double
我的问题是可以提升标准 C++ 枚举,但无法提升 C++11 枚举类(编译器不会生成警告)。我希望 Promotion 使用常规枚举,但忽略 C++11 枚举类。
如何区分“Promote”模板别名中的枚举类和枚举?
这是一个可能的解决方案:
#include <type_traits>
template<typename E>
using is_scoped_enum = std::integral_constant<
bool,
std::is_enum<E>::value && !std::is_convertible<E, int>::value>;
该解决方案利用了 C++11 标准第 7.2/9 段中指定的作用域枚举和无作用域枚举之间的行为差异:
枚举数或无作用域枚举类型的对象的值通过整数提升转换为整数 (4.5)。 [...] 请注意,不为作用域枚举提供这种隐式枚举到 int 的转换。 [...]
以下是如何使用它的演示:
enum class E1 { };
enum E2 { };
struct X { };
int main()
{
// Will not fire
static_assert(is_scoped_enum<E1>::value, "Ouch!");
// Will fire
static_assert(is_scoped_enum<E2>::value, "Ouch!");
// Will fire
static_assert(is_scoped_enum<X>::value, "Ouch!");
}
这是一个活生生的例子 http://liveworkspace.org/code/41HfPq%2411.
致谢:
谢谢丹尼尔·弗雷 https://stackoverflow.com/users/2073257/daniel-frey指出我以前的方法只有在没有用户定义的重载的情况下才有效operator +
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)