假设我正在用一个可玩的人工智能编写一个棋盘游戏。class Board采用两个模板参数:P和N是玩家的数量。P为unique_ptr<Player>或Player。我在实际玩游戏时使用unique_ptr<Player>,因为Player有两个子类(Human和AI),但是当AI搜索游戏状态时,它使用相同的Board类,但使用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_;
};编译器错误:
发布于 2015-01-13 01:38:22
我不会评论这背后的逻辑,但是实现它只需要引入一个助手函数:并使用助手的返回类型。您在尝试中看到的问题是,您的operator[]刚刚返回了P& --如果P是std::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)。
发布于 2015-01-13 00:44:14
另外,可以随意评论设计(例如,在理论上,我真的可以通过引入P来看到性能的提高吗?)
好的,下面是:
1. It compiles
2. It works
3. It's logically correct, bug free and does not leak resources
4. It's easy to maintain
5. It really is easy to maintain
6. Your users enjoy using it
7. At this point you're allowed to attempt to fulfil your narcissistic fantasy about writing the most efficient code you can write (usually for no good reason). You will fail and you really do have better things to do - like making the game better and more fun to play.
担心性能的时候是当你的用户被完美工作的软件所宠坏时,他们唯一可以担心的就是游戏每秒只给他们299.99帧,他们认为这真的应该是300帧。
https://stackoverflow.com/questions/27912721
复制相似问题