【问题标题】:A case where something could bind to a non-const ref but not to a const ref?某些东西可以绑定到非 const ref 但不能绑定到 const ref 的情况?
【发布时间】:2018-01-10 10:03:43
【问题描述】:

小问题

请考虑以下功能:

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

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

是否存在调用f1 的表达式,其中不能用f2 替换f1

上下文

在提供工作机会时,我被要求“编写方法 double approx(vector<Point>& pts)Point 被给出),它使用来自 pts 的点来近似已知以类似布冯的方式保持不变。

我编写了一个定义double approx(vector<Point> const& pts) 的实现(注意const)。由于一个尚未确定的原因,我没有通过测试!

在删除所有可能的解释后,我对测试平台和抓人const 限定符存有疑问......他们的测试程序是否有可能与double approx(vector<Point>& pts) 一起工作,但不能与double approx(vector<Point> const& pts) 一起工作?

【问题讨论】:

  • 如果你在参数列表中看到vector而不是std::vector的测试,也许你不应该相信它。 ;)
  • 会不会是测试使用了它希望你实现的函数签名?如果是这样,那你就不走运了。但无论如何你都不想在那里工作:-)
  • 应该提到,在骨架答案的开头有一个很大的using namespace std;。但我们不要分道扬镳。
  • 我终于从测试作者那里得到了答案。事实上,我输入的代码被逐字插入到测试程序中,就像#include "contestant_code.cc" 那样。在骨架答案中是一个起始using namespace std;,我将其删除......测试程序期待vector<Point>编译;它没有了。 => 测试失败。

标签: c++ reference constants signature


【解决方案1】:

如果你的问题承认疯狂的答案:

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)将运算符转换为某个包装的矢量成员? 似乎不合理......但并非不可能)

【讨论】:

  • 有趣...实际上这只是由于 const-ness 不好(通常应该是operator NTC const&() const;)而导致的——实际上不是函数调用导致了问题,而是分配给参数(将 foo 分配给普通引用变量时会出现同样的问题......)。仍然,有效的例子,恭喜......
  • @Aconcagua 是的,这是一个非常疯狂的例子;一个更合理的例子可能是失败的模板化运算符 T&&()...
  • 奥奇,这讨厌!这回答了我的问题(我很快就会接受),并且倾向于确认像我一样添加这个const 限定符并没有什么根本错误。谢谢。
  • 查看我对给出底线的问题的评论。
【解决方案2】:

如果有这样的表达式(除了 f2 因任何原因无法访问的情况),那将完全破坏我自己的 C++ 知识......

我认为您更有可能在您的函数中实现了一个最小的错误(您还没有意识到)导致失败;但是,不能排除测试评估软件愚蠢到只能寻找修复程序,给定签名,无论您的是否兼容......

【讨论】:

  • 你证实了我的怀疑......而且我还没有(再次)挖掘这些路径(我的错误或他们的错误)。我仍然希望在这里学到一些东西。
  • 我愿意,但我被要求不要在公司外分享。一些比我更有经验的开发人员目前正在研究它。
  • 查看我对给出底线的问题的评论。
猜你喜欢
  • 2019-07-17
  • 2022-08-19
  • 1970-01-01
  • 2014-12-17
  • 2016-09-09
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多