When I have the class:
template <std::same_as<char> ... Indices>
struct MIndices {
std::tuple<Indices...> indices;
MIndices() = delete;
constexpr explicit MIndices(Indices... args) : indices(args...) {
}
};
The following call works:
MIndices myI('i', 'j', 'l', 'z');
But changing the template to the following:
template <size_t Dims, std::same_as<char> ... Indices>
struct MIndices {
std::tuple<Indices...> indices;
MIndices() = delete;
constexpr explicit MIndices(Indices... args) : indices(args...) {
}
};
And then calling it with
MIndices<4> myI('i', 'j', 'l', 'z');
suddenly fails to deduce the arguments.
Why and how can I fix this?
So in principle I would just like to have a compile-time way to specify the number of tuple arguments. If this is a bad way for doing it please tell me.
I am using c++20. (gcc-12.1)
If Dims
should equal the number of parameters passed, you should use the sizeof...
operator instead of letting the caller specify the size.
CTAD (class template argument deduction) only works when all template arguments of the class are deduced.
The workaround is to let all arguments be deduced. You can wrap the class that deduces the indices into another one that can have the size given explicitly:
#include <iostream>
#include <tuple>
template <size_t Dims>
struct wrapper {
template <std::same_as<char> ... Indices>
struct MIndices {
std::tuple<Indices...> indices;
MIndices() = delete;
constexpr explicit MIndices(Indices... args) : indices(args...) {
}
};
};
int main() {
wrapper<4>::MIndices myI('i', 'j', 'l', 'z');
}