【发布时间】:2019-11-08 14:04:37
【问题描述】:
考虑以下问题:我有许多类,每个类都实现一个get() 函数。以下container1 和container2 是此类类的示例:
struct expensive_type {
int v;
};
struct container1 {
expensive_type get() const {
return { 1 };
}
};
struct container2 {
expensive_type x;
expensive_type& get() {
return x;
}
};
我想创建一个包装器,以C 和F 为模板,实现与C 相同的get() 功能,但将函数应用于结果:
template<typename C, typename F>
struct wrapper {
F f;
C c;
decltype(auto) get() {
return f(c.get());
}
};
我现在想为一个简单的包装器创建一个函数f,它只是简单地返回其参数不变。我认为这会起作用:
auto f = [](auto&& x) -> decltype(auto) {
return forward<decltype(x)>(x);
};
wrapper<container1, decltype(f)> trivial_wrapper1 { f, {} };
wrapper<container2, decltype(f)> trivial_wrapper2 { f, {} };
,但不幸的是trivial_wrapper1.get() 返回expensive_type{0} 而不是expensive_type{1}(至少带有-O2 标志)。我猜这个问题与悬空引用有关,但我不知道如何解决它。
我的问题是:如何正确实现函数f,使其充当完美的身份,而无需复制其参数?
为了澄清,以下是预期行为的示例:
cout << trivial_wrapper1.get().v << endl; // should print 1, prints 0 as of now
trivial_wrapper2.get().v = 2;
cout << trivial_wrapper2.c.x.v << endl; // should print 2, and it does as of now
【问题讨论】: