【问题标题】:&* for raw pointer, iterator and ... std::nullptr_t&* 用于原始指针、迭代器和 ... std::nullptr_t
【发布时间】:2012-08-31 17:22:19
【问题描述】:

我有一个启用(通过 std::enable_if)的模板函数,它的参数是原始指针,或者具有 std::iterator 类别,或者是 std::nullptr_t。在该函数中,原始指针(数据成员)被设置为等于参数,如下所示:

template<class T> void myFunction(T it) 
{
    _ptr = &*it;
}

&* 适用于指针和迭代器...但对于 std::nullptr_t 则失败。是否有任何解决方案可以避免编写 2 个不同的函数?

谢谢。

【问题讨论】:

  • 如果*it 的类型已经重载了operator&amp;,即使&amp;*it 也将不起作用。

标签: c++ pointers reference nullptr


【解决方案1】:

最简单的方法是将函数更改为具有两个重载,一个用于原始指针/nullptr_t,它只存储值,另一个由 SFINAE 选择用于当前实现的迭代器,尽管您应该注意,这将在以下情况下失败在某些情况下(特别是如果iterator::value_type 重载一元operator&amp;)。

【讨论】:

    【解决方案2】:

    与往常一样,我们可以使用 trait 来解决这个问题。这一次,我们不要写一个完整的类,因为一个简单的函数重载就足够了。

    #include <cstddef>
    #include <memory>
    
    template <typename T>
    T get_addr(T t) { return std::addressof(*t); } // #1
    
    std::nullptr_t get_addr(std::nullptr_t np) { return np; }
    

    用法:

    T _ptr = get_addr(it);
    

    (如果T 指向的类型重载operator&amp;,则此特征也有效。)

    邀请您使用与主模板中相同的enable_if 条件来保护#1 过载。

    【讨论】:

    • “和往常一样,这一次是一个特质”
    • 你最好也制作一个特殊的指针,以防止取消引用不指向有效内容的指针。 template &lt;typename T&gt; T* get_addr(T* t) { return t;}
    • @nightcracker:我假设 OP 只会在 enable-if'ed 函数中使用它。否则你当然是对的。
    • @KerrekSB:你永远不知道。添加它会不会很痛?如果你不介意,我可以做到。
    • @Mr.Anubis:没错,这就是为什么我更喜欢在这种情况下设置函数重载,而不是一组类模板特化。
    猜你喜欢
    • 2012-09-07
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 2011-05-24
    相关资源
    最近更新 更多