简体   繁体   English

带有std :: is_reference的std :: enable_if无法编译

[英]std::enable_if with std::is_reference fails to compile

Like std::reference_wrapper uses a pointer under the covers to store a "reference", I am trying to do something similar with the following code. 就像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;
}

However, this fails to compile: 但是,这无法编译:

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&&’

How can I make the enable_if return true for reference parameters? 如何使enable_if为参考参数返回true?

T in this case will never be deduced to be a reference type. 在这种情况下, T永远不会被推断为参考类型。 In your construction of the object u2 , the constructor template argument is deduced to be int . 在构造对象u2 ,构造函数模板参数被推导为int

While the type of the variable u2 is int& , when you use u2 in an expression, it is an lvalue expression of type int . 虽然变量u2的类型是int& ,但是当在表达式中使用 u2时,它是int类型的左值表达式。 An expression never has reference type. 表达式永远不会有引用类型。

Template argument deduction uses the types of the function arguments to deduce the template parameter types. 模板参数推导使用函数参数的类型来推导模板参数类型。 Function arguments are expressions. 函数参数是表达式。 Therefore, because no expression has reference type, a template argument will never be deduced to be a reference type. 因此,因为没有表达式具有引用类型,所以模板参数永远不会被推断为引用类型。

[In C++11, if a function argument has type T&& , T may be deduced to the type T& if the argument is an lvalue. [在C ++ 11中,如果函数参数具有类型T&& ,则可以将T推导为类型T&如果参数是左值。 This mechanism enables perfect forwarding. 此机制可实现完美转发。 That's not related to your scenario, though.] 但这与你的情景无关。]

In effect, in an expression, an object and a reference to that object are indistinguishable. 实际上,在表达式中,对象和对该对象的引用是无法区分的。 A reference just allows you to give another name to the object. 引用只允许您为对象指定另一个名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM