其他分享
首页 > 其他分享> > 带有std :: is_reference的c – std :: enable_if无法编译

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

作者:互联网

就像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?

解决方法:

在这种情况下,T永远不会被推断为参考类型.在构造对象u2时,构造函数模板参数被推导为int.

虽然变量u2的类型是int&,但是当在表达式中使用u2时,它是int类型的左值表达式. An expression never has reference type.

模板参数推导使用函数参数的类型来推导模板参数类型.函数参数是表达式.因此,因为没有表达式具有引用类型,所以模板参数永远不会被推断为引用类型.

[在C 11中,如果函数参数具有类型T&&,则T可以推导为类型T&如果参数是左值.此机制可实现完美转发.但这与你的情景无关.]

实际上,在表达式中,对象和对该对象的引用是无法区分的.引用只允许您为对象指定另一个名称.

标签:c,c11,typetraits,enable-if
来源: https://codeday.me/bug/20190902/1788360.html