在参数中强制执行的单一类型的C++参数包

Jea*_*ier 8 c++ variadic-templates c++11 c++14 c++17

我希望能够做到以下几点:

#include <array>
struct blah { };

template<typename... Args>
constexpr auto foo(Args&&... args)
{
    return std::array<blah, sizeof...(Args)>{{ args... }};
}

auto res = foo({}, {});
Run Code Online (Sandbox Code Playgroud)

以下答案并不令人满意:他们只想检查参数包是否为单一类型,但我想在参数中将值正确转换为它(否则它不起作用).

C++参数包,被限制为具有单一类型的实例?

参数包后具有非推导类型的参数

为使用数组,向量,结构等传递给variadic函数或可变参数模板函数的所有参数指定一种类型?

我也不能使用initializer_list,因为我无法计算传递给该array类型的参数数量.我特别不想打字foo(blah{}, blah{});.

我的可能性是什么?

W.F*_*.F. 5

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({}, {});
}
Run Code Online (Sandbox Code Playgroud)

[现场演示]

编辑:

一些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({}, {});
}
Run Code Online (Sandbox Code Playgroud)

[现场演示]

再修改一次:

这个(由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({}, {});
}
Run Code Online (Sandbox Code Playgroud)

[现场演示]