调用const函数而不是非const版本

coy*_*508 24 c++ const

我试图为我的目的包装类似于Qt的共享数据指针的东西,并且经过测试我发现当应该调用const函数时,选择了它的非const版本.

我正在使用C++ 0x选项进行编译,这里是一个最小的代码:

struct Data {
    int x() const {
        return 1;
    }
};

template <class T>
struct container
{
    container() {
        ptr = new T();
    }


    T & operator*() {
        puts("non const data ptr");
        return *ptr;
    }

    T * operator->() {
        puts("non const data ptr");
        return ptr;
    }

    const T & operator*() const {
        puts("const data ptr");
        return *ptr;
    }

    const T * operator->() const {
        puts("const data ptr");
        return ptr;
    }

    T* ptr;
};

typedef container<Data> testType;

void testing() {
    testType test;
    test->x();
}
Run Code Online (Sandbox Code Playgroud)

如您所见,Data.x是一个const函数,因此运算符 - >调用应该是const函数.当我注释掉非常量的那个时,它编译没有错误,所以它是可能的.然而我的终端打印:

"非const数据ptr"

这是一个GCC错误(我有4.5.2),还是有什么我想念的?

Oli*_*rth 27

如果你有两个重载仅在其上不同const-ness,那么编译器解析基于呼叫是否*thisconst或不是.在您的示例代码中,test不是const,因此const调用非重载.

如果你这样做:

testType test;
const testType &test2 = test;
test2->x();
Run Code Online (Sandbox Code Playgroud)

你应该看到另一个重载被调用,因为test2const.

  • @ coyotte508:准确地说.非`constst`重载被认为是更好的匹配. (4认同)
  • 所以如果对象没有被声明为const,编译器会更喜欢调用非const重载,即使它可以调用const重载? (3认同)
  • 从 C++20 开始,你也可以这样做:`testType test; std::as_const(测试).x();` (2认同)

Mar*_*k B 9

test是一个非const对象,因此编译器找到最佳匹配:非const版本.您可以使用constness static_cast:static_cast<const testType&>(test)->x();

编辑:顺便说一句,你怀疑99.9%的时间你认为你发现了编译器错误,你应该重新审视你的代码,因为可能有一些奇怪的怪癖,编译器实际上遵循标准.

  • +1"你可能没有在编译器中发现错误"评论 (2认同)