【发布时间】:2016-02-11 09:38:38
【问题描述】:
我在 C++11 中遇到了一个奇怪的编译错误。
我有一个定义枚举类的模板类:
template <typename Type>
class stats {
public:
// ...
enum class stat {
AVERAGE = (1 << 0),
STANDARD_DERIVATION = (1 << 1),
// ...
};
// ...
};
我目前想在按位运算中使用这个枚举。
例如,以下是该枚举的用法示例:
template <typename Type>
void
stats<Type>::build(stat stats) {
if (stats & stat::AVERAGE)
this->build_average();
if (stats & stat::STANDARD_DEVIATION)
this->build_standard_deviation();
if (stats & stat::PERCENTILES)
this->build_percentiles();
if (stats & stat::LIMITS)
this->build_limits();
}
我们可以像 stats.build(stat::AVERAGE | stat::LIMITS) 这样调用这个函数。
为了在该枚举上使用 & 或 | 运算符而不必每次都手动转换为 int,我定义了运算符:
template<typename T>
using stat_t = typename eip::stats<T>::stat;
template <typename Type>
stat_t<Type>
operator|(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
return static_cast<stat_t<Type>>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
template <typename Type>
stat_t<Type>
operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
return static_cast<stat_t<Type>>(static_cast<int>(lhs) & static_cast<int>(rhs));
}
但是,如果我尝试编译,我会收到以下错误:
error: invalid operands to binary expression ('eip::stats<double>::stat' and 'eip::stats<double>::stat')
if (stats & stat::PERCENTILES)
~~~~~ ^ ~~~~~~~~~~~~~~~~~
candidate template ignored: couldn't infer template argument 'Type'
operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
^
我不明白为什么我的超载被忽略了。似乎编译器为 lhs 和 rhs (eip::stats<double>::stat) 获得了正确的类型,但它无法推断出模板...
此外:
- 显式调用运算符有效 (
operator&<Type>(stats, stat::AVERAGE);) - 我以为问题出在返回类型上,但调用
stat a = stats & stat::AVERAGE;不起作用(与之前的错误相同)。
有什么想法吗?
【问题讨论】:
-
@chris 看起来有点不同。在编译错误消息中,编译器似乎知道应该推导的类型(双):
'eip::stats<double>::stat' and 'eip::stats<double>::stat'。但是,它仍然无法推导出模板。 -
编译器知道你正在传递
stats<double>::stat的参数,但这还不足以推断出Type。如果你有template<> class stats<int> {public: using stat = stats<double>::stat;};怎么办?这可能存在于其他地方,编译器尚无法知道。然后通过stats<double>::stat可以有效地将Type推断为int。 -
好的,所以错误来自基类模板。所以也许解决这个问题的一种方法是在类之外声明枚举?
-
您可以,或者您可以按照链接中的建议使用
Type而不是stat_t<Type>。你永远不会使用Type,除非作为stat_t的参数。
标签: c++ c++11 enums compilation bitwise-operators