代码之家  ›  专栏  ›  技术社区  ›  void.pointer

标准::具有通用参考的is\U指针检查

  •  4
  • void.pointer  · 技术社区  · 7 年前

    我编写了一个函数来检查给定变量是否为指针类型:

    template<typename T>
    void CheckIfPointer(T&& value)
    {
        static_assert(std::is_pointer<typename std::remove_reference<T>::type>::value, "T must be of pointer type");
    }
    

    我在这里使用通用引用,因为我不想限制可以传递的值类别。然而,我注意到在这个例子中:

    char const* mystr = "Hello World";
    CheckIfPointer(mystr);
    

    类型 T 实际上是 const char *& (根据clang)。这也是 remove_reference 这里有合适的解决方案吗?或者有没有一种更简洁的方法来检查实际类型,而不让引用碍事?

    注意,我最多只支持C++14。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Vittorio Romeo    7 年前

    类型 T 实际上是 const char *& (根据clang)。

    完美转发 . 在模板参数推导的上下文中, T&& 不是一个 右值引用 但是 转发参考 相反

    左值 传递给函数模板 转发参考 T& 而不是 T . 这允许 发生: T& && .

    从…起 cppreference :

    如果P是对cv非限定模板参数的右值引用(所谓的转发引用),并且相应的函数调用参数是左值,对A的类型左值引用用于代替A进行推导(注意:这是std::forward操作的基础注意:在类模板参数推导中,类模板的模板参数从来不是转发引用(因为C++17))

    template<class T>
    int f(T&&);       // P is an rvalue reference to cv-unqualified T (forwarding reference)
    template<class T>
    int g(const T&&); // P is an rvalue reference to cv-qualified T (not special)
    
    int main()
    {
        int i;
        int n1 = f(i); // argument is lvalue: calls f<int&>(int&) (special case)
        int n2 = f(0); // argument is not lvalue: calls f<int>(int&&)
    
    //  int n3 = g(i); // error: deduces to g<int>(const int&&), which
                       // cannot bind an rvalue reference to an lvalue
    }
    

    那么,remove_引用是这里的适当解决方案吗?或者有没有一种更简洁的方法来检查实际类型,而不让引用碍事?

    remove_reference 在这里是合适的。您可能想要使用 std::remove_reference_t 避免显式 typename ::type .


    还有,你为什么要传递指针 转发参考 ? 你确定不想通过吗 按价值 通过左值引用 ?

    考虑采取 const T& 相反:

    template<typename T>
    void CheckIfPointer(const T& value)
    {
        static_assert(std::is_pointer<T>::value, "T must be of pointer type");
    }