我希望能够做到以下几点:
#include <array>
struct blah { };
template<typename... Args>
constexpr auto foo(Args&&... args)
{
return std::array<blah, sizeof...(Args)>{{ args... }};
}
auto res = foo({}, {});
以下答案并不令人满意:他们只是想检查参数包是否属于单一类型,但我想在参数中将值正确转换为它(否则它不起作用)。
C++ parameter pack, constrained to have instances of a single type?
Parameter with non-deduced type after parameter pack
我也不能使用 initializer_list,因为我无法计算要传递给 array
类型的参数的数量。
我尤其不想输入 foo(blah{}, blah{});
。
我的可能性是什么?
最佳答案
稍微扩展了一点approach of Jarod42对于懒惰者 (C++17):
#include <utility>
#include <array>
struct blah {};
template <class T, std::size_t I>
using typer = T;
template <class T, std::size_t N, class = std::make_index_sequence<N>>
struct bar_impl;
template <class T, std::size_t N, std::size_t... Is>
struct bar_impl<T, N, std::index_sequence<Is...>> {
static auto foo(typer<T, Is>... ts) {
return std::array<T, N>{{ts...}};
}
};
template <class T = blah, std::size_t N = 10, class = std::make_index_sequence<N>>
struct bar;
template <class T, std::size_t N, std::size_t... Is>
struct bar<T, N, std::index_sequence<Is...>>: bar_impl<T, Is>... {
using bar_impl<T, Is>::foo...;
};
int main() {
bar<>::foo({}, {});
}
编辑:
某些 C++14 解决方案(如 max66 所述)比我预期的还要简单:
#include <utility>
#include <array>
struct blah {};
template <class T, std::size_t I>
using typer = T;
template <class T = blah, std::size_t N = 10, class = std::make_index_sequence<N>>
struct bar;
template <class T, std::size_t N, std::size_t... Is>
struct bar<T, N, std::index_sequence<Is...>>: bar<T, N - 1> {
using bar<T, N - 1>::foo;
static auto foo(typer<T, Is>... ts) {
return std::array<T, N>{{ts...}};
}
};
template <class T>
struct bar<T, 0, std::index_sequence<>> {
static auto foo() {
return std::array<T, 0>{{}};
}
};
int main() {
bar<>::foo({}, {});
}
再进行一次编辑:
这个(正如 Jarod42 所建议的那样)提供了与 OP 问题中完全相同的调用语法:
#include <utility>
#include <array>
struct blah {};
template <class T, std::size_t I>
using typer = T;
template <class T = blah, std::size_t N = 10, class = std::make_index_sequence<N>>
struct bar;
template <class T, std::size_t N, std::size_t... Is>
struct bar<T, N, std::index_sequence<Is...>>: bar<T, N - 1> {
using bar<T, N - 1>::operator();
auto operator()(typer<T, Is>... ts) {
return std::array<T, N>{{ts...}};
}
};
template <class T>
struct bar<T, 0, std::index_sequence<>> {
auto operator()() {
return std::array<T, 0>{{}};
}
};
bar<> foo;
int main() {
foo({}, {});
}
关于在参数中强制执行单一类型的 C++ 参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47470874/