像std::reference_wrapper
使用封面下的指针来存储“引用”,我尝试使用以下代码执行类似操作。
#include <type_traits>
struct Foo
{
void* _ptr;
template<typename T>
Foo(T val,
typename std::enable_if
<
std::is_reference<T>::value,
void
>::type* = nullptr)
: _ptr(&val)
{ }
};
int main()
{
int i = 0;
int& l = i;
Foo u2(l);
return 0;
}
然而,这无法编译:
CXX main.cpp
main.cpp: In function ‘int main()’:
main.cpp:23:13: error: no matching function for call to ‘Foo::Foo(int&)’
main.cpp:23:13: note: candidates are:
main.cpp:8:5: note: template<class T> Foo::Foo(T, typename std::enable_if<std::is_reference<_Tp>::value, void>::type*)
main.cpp:8:5: note: template argument deduction/substitution failed:
main.cpp: In substitution of ‘template<class T> Foo::Foo(T, typename std::enable_if<std::is_reference<_Tp>::value, void>::type*) [with T = int]’:
main.cpp:23:13: required from here
main.cpp:8:5: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
main.cpp:3:8: note: constexpr Foo::Foo(const Foo&)
main.cpp:3:8: note: no known conversion for argument 1 from ‘int’ to ‘const Foo&’
main.cpp:3:8: note: constexpr Foo::Foo(Foo&&)
main.cpp:3:8: note: no known conversion for argument 1 from ‘int’ to ‘Foo&&’
如何使参考参数enable_if
返回true?
答案 0 :(得分:5)
T
永远不会被推断为引用类型。在构造对象u2
时,构造函数模板参数推导为int
。
虽然变量u2
的类型为int&
,但当您在表达式中使用 u2
时,它是{{1}类型的左值表达式}}。 An expression never has reference type.
模板参数推导使用函数参数的类型来推导模板参数类型。函数参数是表达式。因此,因为没有表达式具有引用类型,所以模板参数永远不会被推断为引用类型。
[在C ++ 11中,如果函数参数具有类型int
,如果参数是左值,则T&&
可以推导到类型T
。此机制可实现完美转发。但这与你的情景无关。]
实际上,在表达式中,对象和对该对象的引用是无法区分的。引用只允许您为对象指定另一个名称。