我想只有一个模板功能。所以我想出了......
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;
}
由于N
中的std::array<size_t, N>
,专业化失败了。
这个用例有没有怎么写2函数?
答案 0 :(得分:8)
如果您不想超载的唯一原因是为了避免重复功能体,您可以改为编写自己的特征。一种方式:
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;
}
我还冒昧地将enable_if
移动到模板参数。这样就不能通过为两个参数指定类型名来规避SFINAE(尽管不可否认,对于重载的运算符来说,它不太可能发生)。
另一个很好的事实是,自定义点现在与函数定义本身分离。添加新的iterables只需要为details::writable
添加另一个特化。