私有转换函数导致"模糊的默认类型转换"错误(c ++)

Dre*_*ank 5 c++ g++ type-conversion

首先,一个证明问题的小例子:

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;
}
Run Code Online (Sandbox Code Playgroud)

使用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’
Run Code Online (Sandbox Code Playgroud)

我的理解是,由于结构对象被"切换",编译器将尝试找到转换函数为整数或枚举类型.我明确地向Bar :: Baz枚举类型提供了一个公共转换函数,并希望它能够使用它.

令我困惑的部分是编译器还找到了私有转换函数,然后无法决定使用哪个.为什么甚至考虑私人功能?如果我添加一个显式的强制转换,比如说switch((int)bar),那么只有私有转换函数匹配,并且编译器正确地抱怨它不能使用它,因为它是私有的.那么,由于私有转换函数不能在这种情况下使用,为什么两者之间没有明确的选择呢?

有趣的是,我相信(虽然我不是100%肯定)这个代码在g ++ 4.6上编译时没有错误.

编辑:正如James McNellis在评论中指出的那样,私有转换函数是模板化的事实在这里也是相关的.

jua*_*nza 3

访问控制发生在过载解决之后。这是在标准 \xc2\xa713.3 中指定的

\n\n
\n

重载解析是一种机制,用于在给定作为调用参数的表达式列表和可基于调用上下文调用的一组候选函数的情况下选择要调用的最佳函数。最佳函数的选择标准是参数的数量、参数与候选函数参数类型的匹配程度、对象与隐含对象参数的匹配程度(对于非静态成员函数)以及某些候选函数的其他属性。[注意:\n 不保证重载决议选择的函数适合上下文。其他限制(例如函数的可访问性)可能会导致其在调用上下文中的使用格式不正确。]

\n
\n\n

因此重载决策可以选择一个不适合给定上下文的函数。

\n