将调用哪个过载模板?

时间:2019-03-28 14:08:19

标签: c++ visual-c++ c++17

我有点怀疑,我用C ++编写了一些代码(用于接收裸露的指针):

template< typename T >
auto unwrap_ptr(T smart_ptr){
    //if it some class wich store pointer
    //receive this pointer with method get()
    return smart_ptr.get();
}

template< typename T >
auto unwrap_ptr(T *nake_ptr){
    //if it naked(simple) pointer return this pointer
    return nake_ptr;
}

如果函数使用裸指针,则返回该指针,否则,它从get()方法返回ptr。 在我脑海中che了一下之后,便产生了怀疑。在我的机器和编译器中它可以工作,但是其他编译器又如何呢?对于这种情况标准怎么说?是UB吗?在某些情况下,如果我将函数裸指针放入函数中,将会调用第一个函数吗?还有第二个小问题(很抱歉,他们在一个地方)

template< typename T >
bool same_type(T x, T y) {
    //if x and y same type(class) return true
    return true;
}


template< typename X, typename Y >
bool same_type(X x, Y y) {
    //if x and y different type(class) return false
    return false;
}

我认为这将是可行的,或者在某些情况下将是危险的代码?

1 个答案:

答案 0 :(得分:3)

  

如果函数使用裸指针,则返回该指针,否则,它从get()方法返回ptr。在我脑海中che了一下之后,便产生了怀疑。在我的机器和编译器中它可以工作,但是其他编译器又如何呢?对于这种情况标准怎么说?是UB吗?在某些情况下,如果我将函数裸指针放入函数中,将会调用第一个函数吗?

此方法合理,定义明确且可移植。没有UB!

但是,由于不能复制unique_ptr,因此它的局限性在于您将无法传递unique_ptr。考虑将const T&带入第一个函数,然后添加另一个带const T&&但被删除的函数(以防止临时使用,由于临时指针,该函数非常危险!)。

template< typename T >
auto unwrap_ptr(const T& smart_ptr){
    //if it some class wich store pointer
    //receive this pointer with method get()
    return smart_ptr.get();
}

template< typename T >
auto unwrap_ptr(const T&& smart_ptr) = delete;

template< typename T >
auto unwrap_ptr(T *nake_ptr){
    //if it naked(simple) pointer return this pointer
    return nake_ptr;
}

#include <memory>

int main()
{
    auto sptr = std::make_unique<int>(42);
    int x = 43;

    unwrap_ptr(sptr); // ok
    //unwrap_ptr(std::make_unique<int>(42));  // prohibited
    unwrap_ptr(&x); // ok
}

live demo

C ++ 20将具有std::to_address,它执行相同的操作,尽管乍看之下似乎没有上述针对临时人员的保护,这实在令人遗憾。可能是“如果需要,让程序员处理此问题”的情况;最终,无论如何,您将必须注意返回的原始指针的寿命。


  

第二个小问题(很抱歉,他们在一个地方)将在这里
  我认为这将是可行的,或者在某些情况下将是危险的代码?

是的,也很好。

但是,我们通常为此使用std::is_same_v。要将扣除额带回去,您可以将其包装:

#include <type_traits>

template <typename X, typename Y>
bool same_type(const X&, const Y&)
{
   return std::is_same_v<X, Y>;
}