【发布时间】:2015-04-11 14:52:37
【问题描述】:
考虑以下代码:
#include <iostream>
#include <tuple>
#include <utility>
// A.
template <typename... Args>
void f (const char* msg, Args&&... args)
{
std::cout << "A. " << msg << "\n";
}
// B.
template <typename... Args>
void f (const char* msg, std::tuple<Args...>&& t)
{
std::cout << "B. " << msg << "\n";
}
struct boo
{
const std::tuple<int, int, long> g () const
{
return std::make_tuple(2, 4, 12345);
}
};
int main ()
{
f("First", 2, 5, 12345);
f("Second", std::make_tuple(2, 5, 12345));
boo the_boo;
f("Third", the_boo.g());
f("Fourth", std::forward<decltype(std::declval<boo>().g())>(the_boo.g()));
return 0;
}
输出将是:
A. First
B. Second
A. Third
A. Fourth
从输出很明显,它没有做我想做的事,也就是说我希望 Third 和 Fourth 通过 B. 版本的函数。 Fourth 调用中的 std::forward 是多余的,因为那里不会发生完美的转发。为了有完美的转发,我知道:
- 我必须在类型推导上下文中有一个右值引用
- 参数的类型必须是函数的模板类型
我知道它不起作用。但我没有完全掌握:
为什么使用 std::tuple 改变了上下文,导致它无法按预期工作?为什么模板参数不能是类型 对于另一个模板类型?
我怎样才能(优雅地)修复它?
【问题讨论】:
-
B的更大问题是您的非 const 右值引用无法绑定到 const 右值。 -
我明白了。编译器告诉我同样的事情(有一点代码修改)。我只是不知道如何解决它。
-
没有
g返回一个常量元组? (为什么它会返回一个呢?) -
@T.C.阅读 C++11“Effective C++”系列之前的内容。
-
@celavek,不要返回 const 值,这是一个可以追溯到另一个十年并阻止移动语义的坏习惯。我不确定 Meyers 但 Sutter 不再建议返回 const 值。无论如何,它总是有可疑的好处。
标签: c++ tuples perfect-forwarding