【问题标题】:Freaky output: why would this code give any meaningful output, let alone this?奇怪的输出:为什么这段代码会给出任何有意义的输出,更不用说这个了?
【发布时间】:2013-12-26 15:26:25
【问题描述】:

我什至不知道如何表达我的问题,但我们开始吧......

所以,我有这个类,operator[] 的主体为空(尚未实现)。不过,当我从main() 调用它时,它会产生一个输出。更重要的是,输出正是上一行中分配给它的内容。

EDIT:我添加了一个名为emptyValue的私有属性,并在类构造函数中将其初始化为TipVrijednosti()

这是一个例子:

  template<typename TipKljuca, typename TipVrijednosti>
    class BinStabloMapa : public Mapa<TipKljuca, TipVrijednosti>
    {
            .
            .
        TipVrijednosti &operator[] (const TipKljuca &kljuc) {
            return emptyValue;
        }
        const TipVrijednosti &operator[] (const TipKljuca &kljuc) const {
            return emptyValue;
        }
            .
            .
    }

    int main()
    {
        BinStabloMapa<int, int> m;
        m[100] = 200;
        cout << m[100] << endl;
        return 0;
    }

    OUTPUT: 200

谁能告诉我为什么会这样?

【问题讨论】:

  • 你也可以在你的代码 sn-p 中使用英文:P
  • 很可能是构建问题或从真实代码中创建问题时的问题。 @P0W:完全不同意,问题应该有失败的真实代码,我很厌倦人们为了询问和隐藏问题而按摩代码。我会在任何一天使用任何语言的真实代码,然后再使用英语的错误代码。
  • TipVrijednosti() 返回什么?
  • 使用了什么“怪异”的编译器?
  • @P0W:需要明确的是:我根本不知道那种语言。如果我猜我会说它看起来像波兰语或相关的,但我不理解任何标识符,但您无需了解 TipKljuca 的含义即可知道它是 转换为某种形式的映射(我会使用K 作为模板参数,它与英语不太接近——从模板参数和operator[] 的参数类型推导出来)。

标签: c++ templates operator-overloading cout generic-programming


【解决方案1】:

您的行为未定义,因为您没有从具有非void 返回类型的函数返回任何内容。

§6.6.3:

从函数的末尾流出相当于没有值的返回;这会导致返回值的函数出现未定义的行为。

§1.3.24:

未定义的行为
本国际标准没有要求的行为

【讨论】:

  • 好的,所以我添加了return语句,没有任何改变。
  • @IrfanKahvedzic 那么emptyValue 是什么?
  • @IrfanKahvedzic 如果emptyValue 是一个成员变量,那么现在,正如您所指出的,那么您不再处于 UB 领域。由于operator [] 返回对emptyValue 的引用,因此m[100] = 200; 行实际上是在分配给它。
  • 好吧,因为这是一个泛型类,我不能只返回 0,因为 TipVrijednosti 不必是整数。因此我返回了 TipVrijednosti(),这是对其构造函数的调用。 (emptyValue=TipVrijednosti())
  • @SeanCline 是的,我也想过,但并不完全确定。谢谢。
【解决方案2】:

没有那么大的难题。您的 operator [] 正在返回对某个名为 emptyValue 的数据变量的引用。

            m[100] = 200;

等同于

            m.emptyValue = 200;

然后你写 cout

就像

            cout << m.emptyValue;

注意:索引“100”无关紧要。

【讨论】:

  • "注意:索引 '100' 无关紧要。" +1
【解决方案3】:

这没什么:

#include <iostream>
using namespace std;
template<typename TipKljuca, typename TipVrijednosti>
class BinStabloMapa /* : public Mapa<TipKljuca, TipVrijednosti> */ 
//comment inheritance to make it compile, not relevant to the problem
{
    //C++11 syntax, not relevant either
    TipVrijednosti emptyValue=TipVrijednosti();
    public:    
    TipVrijednosti &operator[] (const TipKljuca &kljuc) {
        return emptyValue;
    }
    const TipVrijednosti &operator[] (const TipKljuca &kljuc) const {
        return emptyValue;
    }


};

int main()
{
    BinStabloMapa<int, int> m;
    m[100] = 200; //calls no const operator[], thus emptyValue is changed 
    cout << m[100] << endl; //calls const operator[], thus emptyValue is return
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2022-06-13
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    相关资源
    最近更新 更多