【发布时间】:2021-06-20 06:19:27
【问题描述】:
在下面的代码中,我制定了一个编译时嵌套循环,它调用一个将数字打印到屏幕的print 函数。 1D 和 2D 版本工作,但 3D 版本触发 note: candidate template ignored: failed template argument deduction 错误。我做错了什么?
#include <functional>
#include <iostream>
// 1D processing.
template<int I>
constexpr void print()
{
std::cout << I << std::endl;
}
template<int... Is>
constexpr void test(
std::integer_sequence<int, Is...> is)
{
(print<Is>(), ...);
}
// End 1D.
// 2D processing.
template<int I, int J>
constexpr void print()
{
std::cout << I << ", " << J << std::endl;
}
template<int I, int... Js>
constexpr void print(
std::integer_sequence<int, Js...> js)
{
(print<I, Js>(), ...);
}
template<int... Is, int... Js>
constexpr void test(
std::integer_sequence<int, Is...> is,
std::integer_sequence<int, Js...> js)
{
(print<Is, Js...>(js), ...);
}
// End 2D.
// 3D processing.
template<int I, int J, int K>
constexpr void print()
{
std::cout << I << ", " << J << ", " << K << std::endl;
}
template<int I, int J, int... Ks>
constexpr void print(
std::integer_sequence<int, Ks...> ks)
{
(print<I, J, Ks>(), ...);
}
template<int I, int... Js, int... Ks>
constexpr void print(
std::integer_sequence<int, Js...> js,
std::integer_sequence<int, Ks...> ks)
{
(print<I, Js, Ks...>(ks), ...);
}
template<int... Is, int... Js, int... Ks>
constexpr void test(
std::integer_sequence<int, Is...> is,
std::integer_sequence<int, Js...> js,
std::integer_sequence<int, Ks...> ks)
{
// THIS CALL FAILS DURING COMPILATION.
(print<Is, Js..., Ks...>(js, ks), ...);
}
// End 3D.
int main()
{
constexpr std::integer_sequence<int, 1, 2, 4, 8> is{};
constexpr std::integer_sequence<int, 1, 2, 4> js{};
constexpr std::integer_sequence<int, 32, 64> ks{};
test(is); // 1D example.
test(is, js); // 2D example.
test(is, js, ks); // 3D example, FAILS.
return 0;
}
【问题讨论】:
-
不幸的是,我不确定为什么这会修复它,但是在 3D
test()函数中,省略了对print()的调用的第二个和第三个模板参数:(print<Is>(js, ks), ...); -
@G.Sliepen。确实,这解决了它。知道为什么会很棒。
-
我的猜测是,在
print<Is, Js..., Ks...>()中,Js...和Ks...之间的边界会丢失,但是如果让它根据参数自动推断,它确实知道边界在哪里。
标签: c++ templates c++17 template-meta-programming