假设我正在编写一个带有可玩 AI 的棋盘游戏。 class Board
有两个模板参数:P 和 N。N 是玩家的数量。 P 是 unique_ptr<Player>
或 Player
.我用 unique_ptr<Player>
实际玩游戏的时候,因为Player
有两个子类(Human
和 AI
),但是当 AI 搜索游戏状态时,它使用相同的 Board
类,但 T = Player(我选择它是为了潜在的性能提升,例如,数据将是本地的,间接性更少,堆应该更少碎片化)。
问题:我如何定义返回对其中一名玩家的引用的运算符[](例如,如果 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_;
};
编译器错误:
- 在非命名空间范围“类 Foo”中的显式特化
- template-id helper,T> 在声明中 主模板
最佳答案
我不会评论这背后的逻辑,但实现它只需要引入一个辅助函数:并使用辅助函数的返回类型。您在尝试中看到的问题是您的 operator[] 刚刚返回 P&
-如果P
,这将是错误的类型是 std::unique_ptr<T,D>
.
要使用助手的返回类型,我们只需将其设为私有(private)静态并依赖 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)
.
关于c++ - unique_ptr 的 remove_pointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27912721/