C++ 理解std::前进
为什么编译器无法推断C++ 理解std::前进,c++,c++11,perfect-forwarding,C++,C++11,Perfect Forwarding,为什么编译器无法推断std::forward的模板参数 我的意思是: #include <memory> #include <iostream> struct X{}; struct A{ A( const X& ) { std::cout << "cpy ctor\n"; } A( X&& ) { std::cout << "move ctor\n"; } }; X foo() { return {}
std::forward
的模板参数
我的意思是:
#include <memory>
#include <iostream>
struct X{};
struct A{
A( const X& ) { std::cout << "cpy ctor\n"; }
A( X&& ) { std::cout << "move ctor\n"; }
};
X foo() { return {}; }
template<typename T,typename Arg>
T* factory( Arg&& a )
{
return new T(std::forward(a));
// ----------^^^^^^^^^^^^^^^ error: can't deduce template parameter
}
int main()
{
factory<A>(foo());
}
#包括
#包括
结构X{};
结构A{
(const X&){std::coutstd::forward
声明如下:
template< class T >
T&& forward( typename std::remove_reference<T>::type& t );
模板
T&转发(typename std::remove_reference::type&T);
typename std::remove\u reference::type
是一个非推断上下文。编译器无法知道应该推断哪个T
,因为它不理解type
成员类型和给定的T
之间的语义联系。它需要搜索所有类型以找到匹配项并能够以某种方式消除冲突的歧义。这是不合理的,因此标准不允许这样做。您必须为转发指定类型的原因是设计上,函数内部的a
发生了什么:
template<typename T,typename Arg>
T* factory( Arg&& a )
{
// 'a' is always an lvalue here
从C++11标准:
14.8.2.5从类型推断模板参数
非推断上下文为:
-使用限定id指定的类型的嵌套名称说明符
-decltype说明符的表达式
-非类型模板参数或数组绑定,其中
子表达式引用模板参数
-在函数的参数类型中使用的模板参数
参数,该参数具有调用中使用的默认参数
正在对其进行参数推导
等等
std::forward
声明如下:
模板
constexpr\u Tp&&forward(typename std::remove\u reference::type&&uu t)无异常
根据上文第一句:
typename std::remove\u reference::type
是非推断上下文。你能澄清这个问题吗?你是在问为什么选择设计来防止参数推断,还是为什么它的实现方式可以防止推断?手动指定类型的目的是让forward
可以决定它是否应该移动ode>a
与否。模板参数推断可以让您确定a
的类型,但不能确定它是否应该移动。@Angew第二个问题。我以为OP问的是一个稍微不同的问题。不管怎样,我还是会把这个问题留在这里。是的,我的错。这个问题不是很清楚。我希望编辑有助于确定是哪一个问题我的麻烦。是的,这正是我所要求的。我认为阅读可以解决剩下的问题。
return new T(std::forward<Arg>(a));
}