【发布时间】:2011-10-12 02:50:28
【问题描述】:
编辑:要明确——马上——这是一个关于现代 C++ 编译器的语言能力的问题。不是关于特定目标的问题。如果不先澄清这一点,就很难描述这样一个抽象的概念,我已经意识到一些混乱围绕着通常做的事情而不是可能做的事情。这是一个非常抽象的问题。这里没有任何东西可以编译,这是故意的。同样,我不是在问如何使这个特定案例工作,而是在问是否有办法让 C++ 识别我想做的事情(通过模板或某种 auto->decltype 技巧最有可能如果甚至可能)。
我对 C++ 并不完全陌生,但肯定不是专家。自从我重新发现语言的力量以来,这是我一直在努力解决的一个基本问题。这里的最终目标是优雅地(并且使用尽可能少的代码)基于调用上下文转发正确的多态返回值。比如……
class A {
public:
A& foo() {
// do something mutant fooish
return *this;
};
};
class B: public A {
public:
B& bar() {
// do something mutant barish
return *this;
};
};
int main(int argc, char** argv) {
B yarp;
yarp.foo().bar();
};
编译错误。有道理,C++ 旨在假设您对自己正在做的事情一无所知(这使得它可以高度优化,但有时会很痛苦……一种中高级 OOP 语言)。
显然,C++ 编译器已经到了这样的地步,他们不仅知道您要求什么(A().foo() 有效,B().foo() 有效),而且还知道您要求什么上下文中您要求它(因此在 C++11 中 auto yarp = B(),编译器知道 yarp 是 B 的一个实例)。有没有办法优雅地利用这一点,而不必重现一堆“使用”语句或包装方法(奇怪的是,它们没有根据 gcc 二进制文件的反汇编得到优化)?
那么这里有什么技巧吗?我根本没有在网上学到的东西。 auto -> decltype 技巧还是模板技巧?示例:
class A {
public:
template <typename R>
R& foo() {
// do something fooish
return (R&)*this;
};
};
class B: public A {
public:
using A::foo<A>; // << even this would be better than nothing (but no where near optimum)
B& bar() {
// do something barish
return *this;
};
};
更简单的东西?如果您将此概念扩展到用于引用计数和 gc 释放的代理模板类的运算符,那么很明显这会产生多大的问题。提前感谢您的任何帮助(哦,第一次在 stackoverflow 上发帖,所以如果我有任何格式错误或您有更好的结构化帖子的建议,请道歉并请指出)。
【问题讨论】:
-
“C++ 旨在假设您对自己在做什么一无所知”,实际上,情况恰恰相反。它的设计假设你知道你在做什么。
-
如果定义在不同的编译单元(不可用),你必须假设一切都必须工作。所以,没有办法知道
foo返回什么。明天程序员可能会来,有时会返回*this,有时会返回static A a; return a;。 -
@R. Martinho Fernandes - 措辞不佳,同意。我想说的(很糟糕)是 C++ 采用了一种非常中级的语言方法来解决问题。这意味着除非您明确告诉它要做什么,否则它会变得盲目(在许多情况下,明显的例外是模板参数扩展)。结果是您必须明确定义动作/身份/等的流程,而不是知道它将隐式地正确解析/识别/等。基本上,它假定您无法跟踪头脑中的隐含事件链(因此,它假定您不知道自己在做什么)。
-
@R. Martinho Fernandes - 反过来看,你是完全正确的,它假设你知道你在做什么,因为你需要告诉它什么是正确的。
-
@UncleBens - 好点。这样就可以 100% 排除非模板解决方案。任何基于模板的?
标签: c++ templates inheritance c++11