c++ - 定义不返回值的 C++ 转换运算符

标签 c++ c++11

在下面的示例中,请注意 A::operator B() 不返回值。

#include <stdio.h>

using namespace std;

struct B
{
    int valb;
    B(int x = 10) : valb(x) {
        printf("\nB::B()...\n");
    }
    B(const B& rhs) : valb(rhs.valb) {
        printf("\nB::B(const B&)...\n");
    }
    B(B& rhs) : valb(rhs.valb) {
       printf("\nB::B(B&)...\n");
    }
    void f() const {
        printf("\nB::f() const... [%d | 0x%x]\n", valb, this);
    }
    ~B() {
        printf("\nB::~B()...\n");
    }
};

struct A {
    static int gv;
    int *vala;
    A(int *x = &gv) : vala(x) {
        printf("\nA::A()...\n");
    }
    A(const A& rhs) : vala(rhs.vala) {
        printf("\nA::A(const A&)...\n");
    }
    void f() const {
        printf("\nconst A::f()...\n");
    }
    operator B () {
        printf("\nA::operator B()... [0x%x]\n", this);
        // return B();
    }
};

void func(const B& barg) {
    printf("\nfunc(const B&)...\n");
    barg.f();
}

int A::gv;

int main ()
{
    A a1;

    func(a1);

    return 0;
}

当使用 g++ 4.5.2 (-std=gnu++0x -fno-elide-constructors) 在 rhel5 中构建时,生成以下输出:

A::A()...

A::operator B()... [0x1cc30200]

func(const B&)...

B::f() const... [4196240 | 0x1cc30210]

B::~B()...

请注意,显示的 2 个不同地址表示正在创建 2 个不同的对象。

问题:

  1. 为什么没有调用任何 B 构造函数?

  2. func() 中,如何创建调用 B::f() 的 B 对象?

  3. g++ 不应该产生编译错误吗?

  4. 标准的第 12.3.2 节中是否有任何提示可以使上述输出有效/符合预期?

最佳答案

首先,它是未定义的行为,因为转换运算符不返回任何内容。

Why isn't any B constructor invoked?

因为程序中没有创建B对象。

Within func(), how is the B object over which B::f() is called, created?

它不是创建的。该程序具有未定义的行为,假设引用引用了一个 B 对象,但是在该内存位置没有 B 对象(由于创建失败在 运算符 B 中。

Shouldn't g++ have generated a compilation error?

有了足够高的警告,也许还有一些优化级别,您就会收到警告。该标准不需要诊断,因此这只是实现质量。

Is there any hint in the standard's Section 12.3.2 that would make the above output valid/expected?

没有什么可以使预期的,但它显然符合标准,因为您的程序会导致未定义的行为,无论编译器做什么,无论您看到什么,都是 undefined 的一个有效化身行为。

关于c++ - 定义不返回值的 C++ 转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21007236/

相关文章:

c++ - 在指针转换期间初始化?

c++ - gcrypt 是针对哪个版本的 PKCS#1 规范实现的?

c++ - 默认生成的移动成员有什么作用?

c++ - 嵌入:单声道与 lua

c# - 如何在 Windows 7 下记录来自非标准按键的按键事件

c++ - “卡住”一个表达式

c++ - alignas() 对 sizeof() 的影响 - 强制性的?

c++ - 为什么这个带有可变模板参数的构造函数不匹配?

c++ - 神秘的 C++ "thing"(函数指针)

c++ - 为什么我可以在 begin() 上使用赋值运算符,即使它是一个右值?