带有两个模板参数的可变模板演绎失败



当我有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)

如果Dims应该等于传递的参数数,您应该使用sizeof...操作符,而不是让调用者指定大小。


CTAD(类模板实参推导)仅在类的所有模板实参都推导出来时才有效。

解决方法是让所有参数都被推导出来。您可以将推断索引的类包装成另一个可以显式给出大小的类:

#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');
}

现场演示

为什么以及如何解决这个问题?

当使用类模板实参推导(又名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
}

如果这样做不好,请告诉我。

您可以选择使用sizeof...(Indices),因此似乎不需要额外的size_t类型的非类型模板参数。

相关内容

  • 没有找到相关文章

最新更新