打印模板参数
Print template parameters
我正在尝试创建一个包含任意数量的 int 参数的模板向量,并创建一个函数来打印这些参数:
namespace ex {
template <int I, class... Ts>
constexpr decltype(auto) get(Ts&& ... ts) {
return std::get<I>(std::forward_as_tuple(ts...));
}
template<int... N>
struct vec
{
static const int size = sizeof...(N);
void print() {
print(size-1);
}
void print(const int n) {
if (n >= 0) {
print(n - 1);
std::cout << ex::get<n>(N...) << std::endl;
}
}
};
}
int main()
{
ex::vec<1, 2, 3> v;
v.print();
}
我收到以下错误:
error C2672: 'ex::get': no matching overloaded function found
error C2975: 'I': invalid template argument for 'ex::get', expected compile-time constant expression
任何人都可以解释一下我是否缺少以及如何实现我期望的行为?
提前致谢。
如果您可以访问 C++17,则可以从中受益 fold expressions:
template<int... N>
struct vec {
void print() {
((std::cout << N << std::endl), ...);
}
};
在C++17之前,你可以使用虚拟数组初始化技巧:
template<int... N>
struct vec {
void print() {
int dummy[]{0, ((std::cout << N << std::endl), 0)...};
(void)dummy;
}
};
第一个零用于处理空 N...
包。第二个零是 comma operator expression. The order of evaluation of arguments in a braced list is fixed by their order in that list [dcl.init.list/4].
的一部分
But what if I want to operate on the individual parameter, for instance, I want to add operator+
which adds 2 vectors. For instance adding vec<1,2,3> v1
and vec<4,5> v2
will result a vec<5,7,3> v3
?
如果包可以有不同的大小,则需要一些技巧。例如:
template<std::size_t... S, int... N, int... M>
auto add_impl(vec<N...>, vec<M...>, std::index_sequence<S...>)
{
constexpr int is1[sizeof...(S)]{N...};
constexpr int is2[sizeof...(S)]{M...};
return vec<(is1[S] + is2[S])...>{};
}
template<int... N, int... M>
auto operator+(vec<N...> v1, vec<M...> v2) {
constexpr auto size = std::max(sizeof...(N), sizeof...(M));
return add_impl(v1, v2, std::make_index_sequence<size>{});
}
我正在尝试创建一个包含任意数量的 int 参数的模板向量,并创建一个函数来打印这些参数:
namespace ex {
template <int I, class... Ts>
constexpr decltype(auto) get(Ts&& ... ts) {
return std::get<I>(std::forward_as_tuple(ts...));
}
template<int... N>
struct vec
{
static const int size = sizeof...(N);
void print() {
print(size-1);
}
void print(const int n) {
if (n >= 0) {
print(n - 1);
std::cout << ex::get<n>(N...) << std::endl;
}
}
};
}
int main()
{
ex::vec<1, 2, 3> v;
v.print();
}
我收到以下错误:
error C2672: 'ex::get': no matching overloaded function found
error C2975: 'I': invalid template argument for 'ex::get', expected compile-time constant expression
任何人都可以解释一下我是否缺少以及如何实现我期望的行为?
提前致谢。
如果您可以访问 C++17,则可以从中受益 fold expressions:
template<int... N>
struct vec {
void print() {
((std::cout << N << std::endl), ...);
}
};
在C++17之前,你可以使用虚拟数组初始化技巧:
template<int... N>
struct vec {
void print() {
int dummy[]{0, ((std::cout << N << std::endl), 0)...};
(void)dummy;
}
};
第一个零用于处理空 N...
包。第二个零是 comma operator expression. The order of evaluation of arguments in a braced list is fixed by their order in that list [dcl.init.list/4].
But what if I want to operate on the individual parameter, for instance, I want to add
operator+
which adds 2 vectors. For instance addingvec<1,2,3> v1
andvec<4,5> v2
will result avec<5,7,3> v3
?
如果包可以有不同的大小,则需要一些技巧。例如:
template<std::size_t... S, int... N, int... M>
auto add_impl(vec<N...>, vec<M...>, std::index_sequence<S...>)
{
constexpr int is1[sizeof...(S)]{N...};
constexpr int is2[sizeof...(S)]{M...};
return vec<(is1[S] + is2[S])...>{};
}
template<int... N, int... M>
auto operator+(vec<N...> v1, vec<M...> v2) {
constexpr auto size = std::max(sizeof...(N), sizeof...(M));
return add_impl(v1, v2, std::make_index_sequence<size>{});
}