【问题标题】:Which of overload templates will be call?将调用哪个重载模板?
【发布时间】:2019-03-28 14:08:19
【问题描述】:

我有一些疑问,我在 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。 并且在我的脑海中检查它之后出现了疑问。在我的机器和编译器中它可以工作,但是其他编译器呢?这种情况标准怎么说?是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;
}

它会按照我的想法工作,或者在某些情况下它会是危险代码?

【问题讨论】:

  • 至少肯定不是UB。 UB 不是这样的……
  • 每个问题一个问题!
  • @L.F.你在关注吗? :)
  • @Rakete1111 我认为这更多的是编译时问题:P
  • 题外话:C++20 引入了std::to_address,这可能很有趣。

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


【解决方案1】:

如果函数接受裸指针,则返回此指针,否则从 get() 方法返回 ptr。并且在我的脑海中检查它之后出现了疑问。在我的机器和编译器中它可以工作,但是其他编译器呢?这种情况标准怎么说?是UB吗?如果我放入函数裸指针,在某些情况下会调用第一个函数吗?

这种方法合理、定义明确且可移植。没有UB!

但是,由于unique_ptr 无法复制,因此您无法将unique_ptr 传递到其中。考虑将const T&amp; 带入第一个函数,然后添加另一个带const T&amp;&amp; 但被删除的函数(以防止临时变量,由于可能的悬空指针,此函数非常危险!)。

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>;
}

【讨论】:

  • 服用T&amp;&amp; 是危险的。您可以在函数退出时被销毁的指针中调用get。采用T const&amp; 并添加一个已删除的T&amp;&amp; 案例将解决此问题。
  • @NathanOliver 嗯doesn't work
  • 糟糕。需要auto unwrap_ptr(const T&amp;&amp; smart_ptr) = delete;。否则T&amp;&amp; 仍然更适合非 const 左值。
  • @NathanOliver 好的,认为我们现在有钱了。谢谢!
  • 没问题。很好的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 1970-01-01
相关资源
最近更新 更多