首先,一个证明问题的小例子:
struct Bar {
enum Baz {aa, bb, cc};
Baz baz_;
operator Baz() const { return baz_; }
private:
template<typename T> operator T() const;
};
int main() {
Bar bar;
switch (bar) {
case Bar::aa:
break;
case Bar::bb:
break;
case Bar::cc:
break;
default:
break;
}
return 0;
}
使用g ++ 4.7.0编译此代码会出现以下错误:
foo.cpp: In function ‘int main()’:
foo.cpp:12:16: error: ambiguous default type conversion from ‘Bar’
foo.cpp:12:16: error: candidate conversions include ‘template<class T> Bar::operator T() const’
我的理解是,由于结构对象被“切换”,编译器将尝试找到转换函数为整数或枚举类型。我明确地向Bar :: Baz枚举类型提供了一个公共转换函数,并希望它能够使用它。
令我感到困惑的是,编译器还会找到私有转换函数,然后无法决定使用哪个。为什么甚至考虑私人功能?如果我添加一个显式的强制转换,比如switch((int)bar)
,那么只有私有转换函数匹配,并且编译器正确地抱怨它不能使用它,因为它是私有的。那么,由于私有转换函数不能在这种情况下使用,为什么两者之间没有明确的选择呢?
有趣的是,我相信(虽然我不是100%肯定)这个代码在g ++ 4.6上编译时没有错误。
编辑正如James McNellis在评论中所指出的那样,私有转换函数的模板化也与此相关。
答案 0 :(得分:3)
在重载解析后访问控制。这在标准§13.3
中规定重载解析是一种机制,用于在给定表达式列表的情况下选择要调用的最佳函数 作为调用的参数和一组可以根据的上下文调用的候选函数 呼叫。最佳函数的选择标准是参数的数量,参数的好坏程度 匹配候选函数的参数类型,如何(对于非静态成员函数) object匹配隐含的对象参数以及候选函数的某些其他属性。 [注意: 由重载决策选择的函数不保证适合上下文。其他 限制(例如函数的可访问性)可以使其在调用上下文中的使用不正确。 ]
因此,重载决策可以选择一个不适合给定上下文的函数。
答案 1 :(得分:-1)
switch(expression)
表达式必须是整数类型或类型,并且有明确的转换为整数类型。