有哪些情况下,某些东西可以绑定到非const引用但不能绑定到const引用?(涉及IT技术)

3

简明问题

请考虑以下函数:

class NonTrivialClass { /* ... */ };

void f1(NonTrivialClass      &) {}
void f2(NonTrivialClass const&) {}

是否有一个表达式可以调用f1,但不能将f1替换为f2

背景

在一份工作的前景中,我被要求“编写方法double approx(vector<Point>& pts)”(给出Point),该方法使用来自pts的点以类似Buffon的方式逼近已知常量。

我已经编写了实现定义double approx(vector<Point> const& pts)的代码(请注意const)。但由于某种原因,我未能通过测试!

在排除所有可能的解释后,我对测试平台和那个关键的const限定符产生了疑问...他们的测试程序是否可以使用double approx(vector<Point>& pts)而不是double approx(vector<Point> const& pts)


如果你在参数列表中看到一个使用 vector 而不是 std::vector 的测试,也许你就不应该相信它。 ;) - Holt
5
测试是否使用其函数签名,并期望您实现?如果是这样,那么你就没什么希望了。但是反正你也不想在那里工作 :-) - juanchopanza
应该提到,在骨架答案的开头有一个很大的 using namespace std;。但是让我们不要偏离主题。 - YSC
我终于从测试编写者那里得到了答案。实际上,我输入的代码被完全照原样插入了测试程序中,就像 #include "contestant_code.cc" 一样。而在骨架答案中有一个开始的 using namespace std;,我将其删除了……测试程序期望编译 vector<Point>,但现在无法编译 => 测试失败。 - YSC
2个回答

5
如果你的问题可以有不合理的答案:
struct NonTrivialClass {};
struct NonTrivialClass2 {
    operator NonTrivialClass&();
    operator NonTrivialClass const&();
};

void f1(NonTrivialClass      &) {}
void f2(NonTrivialClass const&) {}

int main()
{
  NonTrivialClass2 foo;

  f1(foo);
  f2(foo); // error: reference initialization is ambiguous
}

当然,这不适用于vector<>的情况(除非测试机制传递了某种带有损坏(可能是模板、sfinae-unfriendly-whatever)转换运算符的“测试器”对象到某个包装的向量成员?看起来不合理...但并非不可能)。

有趣...实际上这只是由于常量性不好(通常应该是operator NTC const&() const;)才可能发生--实际上,函数调用并没有引起问题,而是对参数的赋值(每当将foo分配给普通引用变量时都会出现相同的问题...)。尽管如此,这仍然是一个有效的例子,恭喜... - Aconcagua
@Aconcagua 是的,那个例子相当疯狂;一个更合理的例子可能是一个失败的模板化运算符 T&&()... - Massimiliano Janes
哎呀,这真是太糟糕了!这回答解决了我的问题(我很快会接受它),并且倾向于确认像我这样添加const限定符没有根本性的错误。谢谢。 - YSC
请查看我在问题评论中给出的底线。 - YSC

1
如果有这样的表达式(除了f2因某种原因无法访问的情况),那将完全打破我的C++知识... 我认为更有可能的是,您在函数中实现了一个微小的错误(您还没有意识到),导致失败;但不能排除测试评估软件太蠢,只是寻找一个修复方案,而不管您的方案是否兼容...

你证实了我的怀疑...我还需要再深入挖掘一下这些路径(是我的问题还是他们的问题导致的错误)。我仍然希望能在这里学到一些东西。 - YSC
我很想分享,但是公司要求我不要在外部分享。目前有比我更有经验的开发人员正在审查它。 - YSC
请���看我在问题评论中给出的底线。 - YSC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接