当前位置: 首页 > 知识库问答 >
问题:

使用C 11实现不同输入类型的C变量模板

游高杰
2023-03-14

最近我做了一个关于现代c的研究。我看到一个视频[在49:00]关于c 11/c 14变量模板。如果你想用不同的模板计算不同类型元组的总和(如int),使用c 11,视频建议一个解决方案:

struct Sum
{
    template<typename T>
    static T sum(T n)
    {
        return n;
    }

    template<typename T, typename... Args>
    static auto sum(T n, Args... rest) -> decltype(n+sum(rest...))
    {
        return n + sum(rest...);
    }
}
auto x = Sum::sum(1, 2.5, 3);

auto无法在c11中推断返回类型,因此必须使用decltype声明返回类型。但有些编译器生成失败,有些编译器生成成功。链接

虽然,使用自动推断返回类型没有问题,我的问题是:

  1. c 11标准是否涵盖了这个问题?如果没有,编译器是否通过自己的实现来处理这个问题?
  2. 为什么最新版本的gcc 8.1编译失败,而gcc 4/5/6/7编译成功?gcc有兼容性问题吗?

顺便说一下,编译错误消息是:

test.cc:20: 16:错误:没有匹配函数的调用求和

 double x = Sum::sum(1, 2.5, 3);

test.cc:12:17:注意:候选模板被忽略:替换失败[with T=int, Args=]:使用未声明的标识符求和

 static auto sum(T n, Args... rest) -> decltype(n + sum(rest...))

测验cc:6:14:注意:候选函数模板不可行:需要单个参数“n”,但提供了3个参数

static T sum(T n)

生成1个错误。

共有1个答案

惠凯歌
2023-03-14

此处尾部返回类型中的函数名查找,

template<typename T, typename... Args>
static auto sum(T n, Args... rest) -> decltype(n+sum(rest...))

在声明此sum之前的上下文中完成,再加上通过ADL(参数相关查找)。

由于该模板在所讨论的类型上调用时无法通过ADL看到,因此该模板无法编译是恰当的。

旧的gcc编译器可能除了使用它们应该使用的上下文之外,还使用了对象上下文。这是一个合理的错误。

您可以轻松解决此问题:

struct Sum {
private:
  template<typename T>
  friend T summer(Sum, T n) {
    return n;
  }
  template<typename T, typename... Args>
  friend auto summer(Sum, T n, Args... rest) -> decltype(n+summer(Sum{},rest...)) {
    return n + summer(Sum{},rest...);
  }
public:
  template<class...Args>
  auto sum(Args...args)->decltype(summer(Sum{}, args...)){
    return summer(Sum{}, args... );
  }
};

在这里,我们强迫一些私人朋友进行ADL。这允许summer的重载在其尾部返回类型中“看到自己”。

 类似资料:
  • 我试图了解System.in input在Java是如何工作的,我创建了一些输入输出代码。我的目标是显示输入到控制台的所有内容,即使输入中有不同类型的变量(例如String、int)交替出现。当我逐行输入数据,并在每行后按Enter键-输出是正确的。但是,如果我将整个输入复制粘贴到控制台,那么在最后一个for循环的第一次迭代之后,代码就会停止,并等待enter。我该怎么做才能使它在没有输入的情况下

  • 我有类似于这个问题用例 我想检查什么类型的实例变量存储在参数中而不引发异常 我想做的是这样的事情 我如何改变这个实现,使它允许我窥视什么类型的参数是持有的 谢谢你的回答,还有几点 我是C++11所以不能使用variant或any 有没有标准的方法。我想要的是一个实例变量的类,可以是多种类型(有界的),并在阅读它时,检查它是什么类型

  • 我在理解如何将另一个类中的动态值分配到其他变量时遇到了一些问题-我尝试使用正确的名称空间、正确的语法并阅读错误提供的文档-但是即使尝试实现所示的示例,也没有运气。我对C#知之甚少,因为我主要从事前端工作,但我必须在我工作的公司里逐步提高并开始学习一些面向后端的东西 我目前的代码如下: BrazeConnectionInputs.cs CreateCampaign.cs

  • 我的函数使用一组给定的输入参数(变量)调用Python函数,并返回包含函数输出的元组(变量,因为输出随调用的函数而变化)。 我正在使用C 11通过MinGW-w64编译器的g端口在视窗10机器上编译。我声明了这个模板变量函数(并调用它)如下: 但是,会引发此错误(为了可读性,缩短为):

  • 想象一下下面的scanario:我有一个程序,它要求输入一个整数,然后是一个String输入。 根据aobe代码,我没有机会输入姓名。因此,通常我会声明2个扫描仪对象,如下所示: 我的问题是:有必要声明多个扫描仪对象来接受不同类型的输入吗??我这样做是正确的吗? 我已经考虑这个问题很多年了。(SO中的几个问题提到了多扫描仪,但他们的问题只使用了一个扫描仪对象,所以我今天问这个问题。)

  • 变量为我们提供了程序可以操作的命名存储。 C ++中的每个变量都有一个特定的类型,它决定了变量内存的大小和布局; 可存储在该内存中的值范围; 以及可以应用于变量的操作集。 变量的名称可以由字母,数字和下划线字符组成。 它必须以字母或下划线开头。 大写和小写字母是不同的,因为C ++区分大小写 - C ++中有以下基本类型的变量,如上一章所述 - Sr.No 类型和描述 1 bool 存储值true