具有两个模板参数的可变参数模板推导失败
variadic template deduction with two template argument fails
当我有 class:
template <std::same_as<char> ... Indices>
struct MIndices {
std::tuple<Indices...> indices;
MIndices() = delete;
constexpr explicit MIndices(Indices... args) : indices(args...) {
}
};
以下调用有效:
MIndices myI('i', 'j', 'l', 'z');
但将模板更改为以下内容:
template <size_t Dims, std::same_as<char> ... Indices>
struct MIndices {
std::tuple<Indices...> indices;
MIndices() = delete;
constexpr explicit MIndices(Indices... args) : indices(args...) {
}
};
然后用
调用它
MIndices<4> myI('i', 'j', 'l', 'z');
突然推论失败
为什么以及如何解决这个问题?
所以原则上我只想有一个编译时的方式来指定
元组参数的数量。如果这样做不好,请告诉我。
我正在使用 c++20。 (gcc-12.1)
Why and how can I fix this?
问题是当使用class模板参数推导(aka CTAD)时,所有模板参数必须由推导过程或默认参数确定。 无法明确指定一些参数并推断出其他参数。
因此,要解决这个问题,您必须显式指定所有模板参数或推导所有模板参数。所以解决这个问题的一种方法是:
MIndices<4, char, char, char, char> myI('i', 'j', 'l', 'z');
也许更简化的示例可能有助于说明这一点:
template<typename T1, typename T2, typename T3>
class Custom
{
public:
Custom (T1 x, T2 y, T3 z)
{
}
};
int main()
{
std::string s;
Custom c(3, 2.343, s); //works
//Custom<int> b(4, 2,343, s); //WON'T WORK
Custom<int, int, std::string> k(4, 4, "s"); //works
}
If this is a bad way for doing it please tell me.
您可以选择使用 sizeof...(Indices)
,因此似乎不需要 size_t
.
类型的额外非类型模板参数
如果 Dims
应该等于传递的参数数量,您应该使用 sizeof...
运算符而不是让调用者指定大小。
CTAD(class 模板参数推导)仅在推导 class 的所有模板参数时有效。
解决方法是推导所有参数。您可以将推导索引的 class 包装到另一个可以明确指定大小的索引中:
#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');
}
当我有 class:
template <std::same_as<char> ... Indices>
struct MIndices {
std::tuple<Indices...> indices;
MIndices() = delete;
constexpr explicit MIndices(Indices... args) : indices(args...) {
}
};
以下调用有效:
MIndices myI('i', 'j', 'l', 'z');
但将模板更改为以下内容:
template <size_t Dims, std::same_as<char> ... Indices>
struct MIndices {
std::tuple<Indices...> indices;
MIndices() = delete;
constexpr explicit MIndices(Indices... args) : indices(args...) {
}
};
然后用
调用它 MIndices<4> myI('i', 'j', 'l', 'z');
突然推论失败
为什么以及如何解决这个问题?
所以原则上我只想有一个编译时的方式来指定 元组参数的数量。如果这样做不好,请告诉我。
我正在使用 c++20。 (gcc-12.1)
Why and how can I fix this?
问题是当使用class模板参数推导(aka CTAD)时,所有模板参数必须由推导过程或默认参数确定。 无法明确指定一些参数并推断出其他参数。
因此,要解决这个问题,您必须显式指定所有模板参数或推导所有模板参数。所以解决这个问题的一种方法是:
MIndices<4, char, char, char, char> myI('i', 'j', 'l', 'z');
也许更简化的示例可能有助于说明这一点:
template<typename T1, typename T2, typename T3>
class Custom
{
public:
Custom (T1 x, T2 y, T3 z)
{
}
};
int main()
{
std::string s;
Custom c(3, 2.343, s); //works
//Custom<int> b(4, 2,343, s); //WON'T WORK
Custom<int, int, std::string> k(4, 4, "s"); //works
}
If this is a bad way for doing it please tell me.
您可以选择使用 sizeof...(Indices)
,因此似乎不需要 size_t
.
如果 Dims
应该等于传递的参数数量,您应该使用 sizeof...
运算符而不是让调用者指定大小。
CTAD(class 模板参数推导)仅在推导 class 的所有模板参数时有效。
解决方法是推导所有参数。您可以将推导索引的 class 包装到另一个可以明确指定大小的索引中:
#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');
}