C ++中的“皮条客我的图书馆”

时间:2017-07-12 16:20:49

标签: c++ scala polymorphism

在Scala中,有一种通常被称为“pimp my library”的设计模式。基本的想法是我们有一些类Foo(可能在某些我们无法修改的库中),我们希望Foo表现得像它有一些方法或行为frobnicate,我们可以使用隐式类在事后添加方法。

implicit class Bar(val foo: Foo) extends AnyVal {
  def frobnicate(): Unit = {
    // Something really cool happens here ...
  }
}

然后,如果我们有一个Foo的实例,我们就可以在其上调用frobnicate,只要Bar在范围内,Scala编译器就足够智能化了将Foo投射到Bar

val foo = new Foo()
foo.frobnicate() // Correctly calls new Bar(foo).frobnicate()

我想在C ++中做同样的事情。我知道C ++有隐式转换,但在访问成员时它们似乎没有触发。举个具体的例子,C ++中的以下代码会产生错误。

class Foo {}; // Assume we can't modify this class Foo

class Bar {
private:
  Foo foo;
public:
  Bar(Foo foo) : foo(foo) {}
  void frobnicate() {
    cout << "Frobnicating :)" << endl;
  }
};

void frobnicate(Bar bar) {
  cout << "Frobnicating :)" << endl;
}

int main() {
  Foo value;
  frobnicate(value);  // This works
  value.frobnicate(); // But this doesn't
  return 0;
}

value.frobnicate()行上,C ++似乎没有在该上下文中寻找隐式转换。

  

main.cc:30:9:错误:'class Foo'没有名为'frobnicate'的成员

注意:我正在使用C ++ 11进行编译。粗略地看一下较新的C ++版本,从那时起,似乎没有什么会影响这个问题。 C ++ 11兼容的解决方案是理想的,但是出于教学目的,在新的C ++版本中执行此操作的方法也会很好。

3 个答案:

答案 0 :(得分:9)

您所描述的内容称为 U nified F unction C 所有 S yntax(UFCS),以及到目前为止,无法在C ++中完成。任何使用D中的范围和算法链接的人都可以证明这将是多么令人惊奇。

缺乏UFCS支持实际上是一般现代智慧使用自由浮动函数和ADL用于任何不需要虚拟或封装的主要原因之一。

有人建议将D&D的UFCS引入该语言,但它仍然只是一个提案:

https://isocpp.org/files/papers/N4165.pdf

编辑:对于想知道我们为什么会想要这个功能的人来说,想象一下能够编写以下内容:

y

答案 1 :(得分:3)

虽然您无法完全按照要求执行操作,但您可以继承Foo并延长它。

class Bar : public Foo{
public:
void frobnicate() {
    cout << "Frobnicating :)" << endl;
  }
}

现在Bar包含Foo所有内容以及新方法。见http://www.cplusplus.com/doc/tutorial/inheritance/

答案 2 :(得分:1)

  

C ++似乎并没有在该上下文中寻找隐式转换。

这是正确的。您正在寻找的机制并不存在于该语言中。