gpt4 book ai didi

c++ - 递归可变参数模板函数 - 没有歧义?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:04:17 29 4
gpt4 key购买 nike

我目前正在研究可变参数模板,作为消化我读过的一些东西的小练习,我写了一个小函数来输出所有参数类型的名称:

#include "stdafx.h"
#include <iostream>
#include <string>

template<typename Next, typename... Rest>
std::string get_arg_types(Next next, Rest... rest)
{
return std::string(typeid(Next).name()) + "\n" + get_arg_types(rest...);
}

template<typename Last>
std::string get_arg_types(Last last)
{
return std::string(typeid(Last).name());
}

int main()
{
float f = 0;
double d = 0;
int i = 0;

std::cout << get_arg_types(f, d, i);

return 0;
}

令我惊讶的是,它使用 VC++ 12.0 编译并且(似乎)工作得很好。

当只剩下一个参数时,由于重载之间的歧义,我预计会出现错误,因为我读到模板参数包可以为空/包含 0 个参数。

所以我的问题是为什么这样做有效? “潜在歧义”如何解决?这两个函数的签名是否仅与 1 个 arg 不相同?我觉得我可能在某处遗漏了一些重要的概念,因为在我看来,上面的示例不应该编译,但显然我错了。

亲切的问候:)

最佳答案

您的代码有问题,但原因不同。如 answer 中所述相关问题Ambiguous call when recursively calling variadic template function overload ,您代码中的第二个重载被认为更专业。但是,它应该出现在带有参数包的例程之前。使用 gcc 8.2.1 或 clang 6.0.1 编译代码会出现如下错误

variadic.cpp: In instantiation of ‘std::__cxx11::string get_arg_types(Next, Rest ...) [with Next = int; Rest = {}; std::__cxx11::string = std::__cxx11::basic_string<char>]’:
variadic.cpp:7:67: recursively required from ‘std::__cxx11::string get_arg_types(Next, Rest ...) [with Next = double; Rest = {int}; std::__cxx11::string = std::__cxx11::basic_string<char>]’
variadic.cpp:7:67: required from ‘std::__cxx11::string get_arg_types(Next, Rest ...) [with Next = float; Rest = {double, int}; std::__cxx11::string = std::__cxx11::basic_string<char>]’
variadic.cpp:23:39: required from here
variadic.cpp:7:67: error: no matching function for call to ‘get_arg_types()’
return std::string(typeid(Next).name()) + "\n" + get_arg_types(rest...);
error: no matching function for call to ‘get_arg_types()

正如您从错误中看到的那样,即使 get_arg_types 具有单个参数,编译器也会选择第一个重载,然后调用不带参数的 get_arg_types。一个简单的解决方案是将带有单个参数的 get_arg_types 的重载移动到带有模板参数包的例程之前,或者在常规之前添加单参数 get_arg_types 的声明例行公事。

或者,您可以消除 get_arg_types 的特化单参数,并添加具有 0 个参数的特化:

std::string get_arg_types()
{
return std::string();
}

同样,这样的特化应该放在(或至少声明)模板例程之前。请注意,对于第二种解决方案,输出略有变化。

关于c++ - 递归可变参数模板函数 - 没有歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53445845/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com