remove_pointer for unique_ptr's

时间:2015-01-12 23:44:40

标签: c++ templates pointers unique-ptr dereference

假设我正在编写一个带有可玩AI的棋盘游戏。 class Board有两个模板参数:P和N.N是玩家数量。 P是unique_ptr<Player>Player。我在实际玩游戏时使用unique_ptr<Player>,因为Player有两个子类(HumanAI),但是当AI搜索游戏状态时,它会使用相同的Board {1}}类,但T = Player(我选择这个来获得潜在的性能提升,例如数据将是本地的,更少的间接性,堆应该更少碎片化)。

问题:我如何定义operator [],它返回对其中一个玩家的引用(例如,如果T = unique_ptr,它返回* arr_ [i],否则返回arr_ [i]) 。以下是尝试,但没有编译。另外,请随意评论设计(例如,理论上,通过引入P,我能真正看到性能提升吗?)。

template<typename P, size_t N>
class Board
{
public:
  P& operator[] (size_t idx) { return helper(arr[idx]); }
private:
  template<typename I, typename O>
  inline O& helper(I& input)
  {
    return input;
  }
  template<>
  inline P& helper<unique_ptr<P>,P>(unique_ptr<P> input)
  {
    return *input;
  }
  std::array<P,N> arr_;
};

编译器错误:

  1. 非命名空间范围中的显式特化&#39;类Foo&#39;
  2. template-id helper,T&gt;在宣言中     主要模板

2 个答案:

答案 0 :(得分:1)

我不会对这背后的逻辑发表评论,但实现它只需要引入辅助函数:并使用帮助程序的返回类型。您在尝试中看到的问题是,您的运营商[]刚刚返回P& - 如果Pstd::unique_ptr<T,D>,则该类型将是错误的类型。

要使用帮助者的返回类型,我们只需将其设为私有静态并依赖decltype

template <typename P, size_t N>
class Board {
private:
    template <typename T, typename D>
    static T& get_helper(std::unique_ptr<T,D>& val) { return *val; }

    template <typename T>
    static T& get_helper(T& val) { return val; }

public:
    decltype(get_helper(std::declval<P&>())) // use the same return type
                                             // as the helper function
    operator[] (size_t idx) {
        return get_helper(arr_[idx]);
   }

private:
    std::array<P,N> arr_;
};

在C ++ 14中,注释掉的行可以只是decltype(auto)

答案 1 :(得分:0)

  
    
      

另外,请随意评论设计(例如,理论上,通过引入P,我能真正看到性能提升吗?)。

    
  

好的就是:

  1. 您尝试在代码编译之前交换可维护性以获得性能。这是最邪恶的早期优化。

  2. unique_ptr管理所有权。将其用作逻辑开关,正如您正在寻求做的那样是交易可维护性和可读性(大时间)以获得尚未确认的性能提升(参见1)。将unique_ptr传递给函数的唯一原因是函数 absoluteley必须知道数据是由unique_ptr管理的。这是罕见的(阅读:永远不要这样做),除非您转移所有权或者您正在编写一个访问者,该访问者旨在访问unique_ptrs的集合

  3. 关于代码最重要的事情是这些(按重要性排序):

    1. 编译
    2. 工作
    3. 它在逻辑上是正确的,无错误且不会泄漏资源
    4. 易于维护
    5. 维护真的很容易
    6. 您的用户喜欢使用它
    7. 在这一点上,你被允许尝试实现你自己写的最有效代码的自恋幻想(通常没有充分理由)。你会失败,你真的有更好的事情要做 - 比如让比赛更好,更有趣。
  4. 担心性能的时候就是当你的用户被如此完美无缺的工作软件所破坏时,使用起来非常愉快,他们唯一可以想到的担心是游戏只给他们299.99帧第二,他们认为真的应该提供300。