Here is my problem:
template <class... Ts>
struct iniClass
{
private:
std::initializer_list<int> m_data;
int x;
public:
iniClass(Ts... vars)
: m_data({vars...}), x(8)
{
std::cout << "created object with first constructor\n";
prin();
}
void prin()
{
for (auto var : m_data)
{
std::cout << var << ", ";
}
std::cout << '\n';
}
};
int main()
{
iniClass<std::initializer_list<int>> il1({1, 2, 3, 4}); // Work like a charm!
iniClass<int...> il2(1, 2, 3, 4); // Didn't work, How to make this work?
}
Can we use int... (,and generally primativeTYPE...) as an argument for template parameter pack directly?
Is there a way to make it work in that way?
No, this feature is currently not part of the C++ standard. The closest thing we have is:
// P1219 proposed syntax
void foo(int... args);
// C++20
void foo(std::convertible_to<int> auto&&... args);
// C++17
template <typename... Ts>
auto foo(Ts&&... args)
-> std::enable_if_t<(std::is_convertible_v<Ts, int> && ...)>;
// C++14
template <typename... Ts>
auto foo(Ts&&... args)
-> std::enable_if_t<CONJUNCTION<std::is_convertible<Ts, int>...>::value>;
// TODO: implement a conjunction trait like std::conjunction
// C++11
template <typename... Ts>
auto foo(Ts&&... args)
-> typename std::enable_if<CONJUNCTION<std::is_convertible<Ts, int>...>::value>::type;
There is a well-received proposal which adds this feature though. See P1219 - Homogeneous variadic function parameters. This proposal has been rejected for C++23 by EWG (Evolution Working Group), however, it is possible that a revised version could make it into a future standard.
It doesn't really look like you need this feature though. You could just use std::array
, which does support construction like:
// std::make_array, (from library fundamentals TS v2) (C++26?)
// you could implement this yourself in C++11
auto arr = std::experimental::make_array<int>(1, 2, 3, 4, 5);
// std::to_array, since C++20
// you could implement this yourself in C++11
auto arr = std::to_array<int>({1, 2, 3, 4, 5});
// CTAD, since C++17
std::array arr{1, 2, 3, 4, 5};
// C++11, works out of the box
std::array<int, 5> arr{1, 2, 3, 4, 5};
// C-style arrays
int arr[] {1, 2, 3, 4, 5};
Your iniClass
is basically an array anyway. Also, it's a bad idea to ever store std::initializer_list
, because it doesn't own its contents. It's like a pointer or reference.