参数包迭代

发布于 2025-01-28 16:51:32 字数 1262 浏览 3 评论 0原文

为什么此代码不编译?

#include <iostream>
#include <typeinfo>

template <typename ...Ts>
void f();

template <typename T>
void f() {
    std::cout << typeid(T).name() << std::endl;
}

template <typename T, typename U, typename ...Ts>
void f() {
    std::cout << typeid(T).name() << ", ";
    f<U, Ts...>();
}

int main(int argc, char** argv)
{
    f<int, float, char>();
}

MSVC编译器错误: 错误C2668:'f':对超载功能预期输出的模棱两可

int, float, char

侧面问题:是否有更现代的方法可以做同样的事情?

编辑 我找到了一种接受零模板包的方法:

#include <typeinfo>
#include <iostream>
#include <type_traits>

template <typename ...Ts>
using is_empty_pack = std::enable_if_t<sizeof ...(Ts) == 0>;

template <typename ...Ts, typename = is_empty_pack<Ts...>>
void f() {}

template <typename T, typename ...Ts>
void f() {
    std::cout << typeid(T).name();
    if constexpr (sizeof ...(Ts) > 0) std::cout << ", "; else std::cout << std::endl;
    f<Ts...>();
}

int main(int argc, char *argv[])
{
    f<>();
    f<int>();
    f<int, float>();
}

还有其他建议吗?

Why this code doesn't compile ?

#include <iostream>
#include <typeinfo>

template <typename ...Ts>
void f();

template <typename T>
void f() {
    std::cout << typeid(T).name() << std::endl;
}

template <typename T, typename U, typename ...Ts>
void f() {
    std::cout << typeid(T).name() << ", ";
    f<U, Ts...>();
}

int main(int argc, char** argv)
{
    f<int, float, char>();
}

MSVC compiler error:
error C2668: 'f': ambiguous call to overloaded function

Expected output:

int, float, char

Side question: would there be a more modern way to do the same thing ?

EDIT
I've found a way to accept zero template pack:

#include <typeinfo>
#include <iostream>
#include <type_traits>

template <typename ...Ts>
using is_empty_pack = std::enable_if_t<sizeof ...(Ts) == 0>;

template <typename ...Ts, typename = is_empty_pack<Ts...>>
void f() {}

template <typename T, typename ...Ts>
void f() {
    std::cout << typeid(T).name();
    if constexpr (sizeof ...(Ts) > 0) std::cout << ", "; else std::cout << std::endl;
    f<Ts...>();
}

int main(int argc, char *argv[])
{
    f<>();
    f<int>();
    f<int, float>();
}

Any other suggestion?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小嗲 2025-02-04 16:51:32

用G ++编译可以清楚地解释正在发生的事情:

prog.cc: In function 'int main(int, char**)':
prog.cc:20:24: error: call of overloaded 'f<int, float, char>()' is ambiguous
   20 |     f<int, float, char>();
      |     ~~~~~~~~~~~~~~~~~~~^~
prog.cc:5:6: note: candidate: 'void f() [with Ts = {int, float, char}]'
    5 | void f();
      |      ^
prog.cc:13:6: note: candidate: 'void f() [with T = int; U = float; Ts = {char}]'
   13 | void f() {

您提供了三种不同的模板功能F,其中两个可以匹配您在此处写的内容。

编辑:也许您认为第一个是声明,另外两个是专业化,但这不是模板的工作方式。专业意思是指专业化特定模板参数的类型或价值,而不是专门研究模板参数的数字

删除

template <typename ...Ts>
void f();

将使程序编译并以预期行为运行。

Compiling with g++ gives a pretty clear explanation of what's happening:

prog.cc: In function 'int main(int, char**)':
prog.cc:20:24: error: call of overloaded 'f<int, float, char>()' is ambiguous
   20 |     f<int, float, char>();
      |     ~~~~~~~~~~~~~~~~~~~^~
prog.cc:5:6: note: candidate: 'void f() [with Ts = {int, float, char}]'
    5 | void f();
      |      ^
prog.cc:13:6: note: candidate: 'void f() [with T = int; U = float; Ts = {char}]'
   13 | void f() {

You've provided three different templated functions f, two of which could match what you've written here.

EDIT: Maybe you thought the first one was a declaration and the other two are specializations, but that's not how templates work. Specialization means specializing the type or value of a particular template argument, not specializing the number of template arguments.

Deleting

template <typename ...Ts>
void f();

will make the program compile and run with the expected behavior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文