模板化(或以某种方式自动)方法的返回值

Templating (or somehow autoing) the return value of methods

本文关键字:方式自 方法 返回值      更新时间:2023-10-16

编辑:首先澄清一下,这是一个关于现代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++编译器方位了,他们不仅知道你要求((). foo()的工作原理和B () . foo()工作的情况),但是也在什么情况下你的要求(因此汽车yarp = B()在c++ 11中,编译器知道yarp B)的一个实例。有办法利用这个优雅而不用复制一堆的"using"语句或包装方法(奇怪的是没有得到优化根据拆卸的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上的第一篇文章,所以如果我有任何格式错误,或者你有更好的结构化文章的建议,请向周围道歉,并指出来)。

最明显的解决方案就是将它分成两行:

yarp.foo();
yarp.bar();

或者使用static_cast's返回对B&的引用,因此

static_cast<B&>(yarp.foo()).bar();

同意,这有点冗长,但是像这样将层次结构中的多个成员函数调用链接在一行中对于c++来说是非常不寻常的语法。它只是不经常出现,所以语言不太支持这个习语。我从来没有遇到过这样的情况。

如果你想设计一些可链接的功能,你可以使用其他更好的习惯用法。Boost的Range Adaptors就是一个例子,它重载操作符|来实现链接。

编辑:另一个选项是重载foo()在B&:
class B: public A {
    public:
        B& foo() { A::foo(); return *this; }
        B& bar() {
            // do something mutant barish
            return *this;
        };
};

我不认为有自动类型检测,因为编译器甚至不知道哪些类将继承A

在你的第二次尝试中,c++禁止using模板特化。所以编译不了

我认为还有一个技巧你可以尝试是使A一个模板

template <typename FinalType>
class A {
    public:
        FinalType& foo() {
            // do something fooish
            return static_cast<FinalType&>(*this);
        };
};
class B: public A<B> {
    public:
        B& bar() {
            // do something barish
            return *this;
        };
};

你声明了一个类B的实例,它没有方法foo -所以难怪会有编译错误-你的意思是吗yarp.bar () . foo ();