如何完善转发成员变量

时间:2019-02-15 12:26:05

标签: c++ perfect-forwarding

考虑以下代码:

template<typename T> void foo(T&& some_struct)
{
    bar(std::forward</* what to put here? */>(some_struct.member));
}

在转发整个结构的情况下,我会做std::forward<T>(some_struct)。但是转发成员时如何获得正确的类型?

我曾经有一个想法是使用decltype(some_struct.member),但这似乎总是产生该成员的基本类型(在struct定义中定义)。

3 个答案:

答案 0 :(得分:12)

在这里,成员访问权限是正确的事情:您只需要std::forward<T>(some_struct).member

经过测试:

template <class... >
struct check;

struct Foo {
    int i;
};

template <class T>
void bar(T &&f) {
    // fatal error: implicit instantiation of undefined template 'check<int &&>'
    check<decltype((std::forward<T>(f).i))>{};
}

int main() {
    bar(Foo{42});
}

答案 1 :(得分:12)

成员访问权限为value category preserving。如果对象表达式是一个左值,则成员访问也是如此,否则它是一个左值(如std::move的结果)。成员访问也要根据对象的转发结果进行。

std::forward<T>(some_struct).member

答案 2 :(得分:4)

正如@StoryTeller解释的那样,如果转发结构,则将保留成员值类别(我谨记这一点很重要)。 但是,转发成员时如何获得正确的类型? 您可以执行以下操作:

template <typename T>
void foo(T&& some_struct) {
    bar(std::forward<decltype(std::declval<T>().member)>(some_struct.member));
}

在此代码中,要转发的实际对象是成员而不是对象。 由于转发只是有条件的举动,因此您可能需要看一下这两篇文章: enter link description here enter link description here