san*_*orn 5 c++ templates template-meta-programming
我想只有一个模板功能.所以我想出来......
template<typename Iteratable, size_t N,
typename =
std::enable_if_t<
std::is_same_v<Iteratable, const std::initializer_list<size_t> > ||
std::is_same_v<Iteratable, const std::array<size_t, N > >
>
>
std::ostream& operator << (std::ostream& os, Iteratable& in) {
std::copy(std::begin(in), std::end(in), std::ostream_iterator<size_t>(os, " ") );
return os;
}
Run Code Online (Sandbox Code Playgroud)
似乎因为Nin std::array<size_t, N>,专业化失败了.
有没有怎么不写这个用例的2函数?
如果你不想重载的唯一原因是为了避免重复功能体,你可以改为编写自己的特征.一种方式:
namespace details {
template<class Iterable>
struct writable : std::false_type {};
template<size_t N>
struct writable<std::array<std::size_t, N>> : std::true_type {};
template<>
struct writable<std::initializer_list<size_t>> : std::true_type {};
template<class Iterable>
constexpr bool writable_v = writable<Iterable>::value;
}
template<typename Iteratable,
std::enable_if_t<details::writable_v<std::decay_t<Iteratable>>,
int> = 0
>
std::ostream& operator << (std::ostream& os, Iteratable& in) {
std::copy(std::begin(in), std::end(in), std::ostream_iterator<size_t>(os, " ") );
return os;
}
Run Code Online (Sandbox Code Playgroud)
我也冒昧地移动enable_if到模板参数.这样就不能通过为两个参数指定类型名来规避SFINAE(尽管可以肯定的是,对于重载运算符来说,它不太可能发生).
另一个很好的事实是,自定义点现在与函数定义本身分离.添加新的迭代只是添加另一个专业化的问题details::writable.