c++ - 带有 std::is_reference 的 std::enable_if 编译失败

标签 c++ c++11 typetraits 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++ - 带有 std::is_reference 的 std::enable_if 编译失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10907743/

相关文章:

c++ - 跟踪打开的子对话框

c++ - 从未执行过的代码中的微小更改如何产生影响?

c++ - 如何在等待时取消 `boost::asio::read` 操作

模板类中的 C++20 类外定义

for-loop - 基于范围的 for 循环而不使用标准库

c++ - 将具有公共(public)头文件的目标文件链接到 main 会给出体系结构 x86_64 错误的重复符号

c++ - 了解 C++11 中 std::function 的模板参数?

c++ - boost::aligned_storage 在返回时像 POD 类型一样复制非 POD 对象

c++ - 是否可以利用 is_trivially_copy_assignable 和 is_trivially_copy_constructible 进行优化?

c++ - 在编译时检查静态函数是否在类中可用