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

clang找不到折叠表达式中的模板二元运算符

陶富
2023-03-14

这是我连接元组的二进制运算符:

template <class... Args1, class... Args2>
constexpr decltype(auto) operator+(const std::tuple<Args1...> &tup1,
                                   const std::tuple<Args2...> &tup2) {
   return std::tuple_cat(tup1, tup2);
}

它在具有两个元组的两个编译器(gcc、clang)上都能完美工作:

template <class Arg1, class Arg2>
constexpr decltype(auto) concat_test(Arg1 &&arg1, Arg2 &&arg2) {
   return arg1 + arg2;
}

但当我尝试在fold表达式中使用它时,如下所示:

template <class... Args>
constexpr decltype(auto) multiple_concat(Args &&... args) {
   return (args + ...);
}

gcc 7.1.1编译它没有任何错误,与clang 5.0不同,它会产生错误输出:

错误:对函数“operator”的调用在模板定义中不可见,也无法通过依赖于参数的查找找到

返回(args...);

注意:在函数模板专门化的实例化中“multiple\u concat”

多个\u concat(tup1,tup2);

注意:“操作员”应在呼叫站点之前声明

constexpr decltype(auto)运算符(const std::tuple

这个代码是否格式错误?clang到底在说什么?

共有3个答案

夏昊
2023-03-14

显然,非限定查找失败。这一个使得它可以用叮当声6编译:

namespace std {
    template <class... Args1, class... Args2>
    constexpr decltype(auto) operator+(const ::std::tuple<Args1...> &tup1,
                                       const ::std::tuple<Args2...> &tup2) {
      return ::std::tuple_cat(tup1, tup2);
    }

    template <class... Args1, class... Args2>
    constexpr decltype(auto) operator+(::std::tuple<Args1...> &&tup1,
                                       ::std::tuple<Args2...> &&tup2) {
      return ::std::tuple_cat(tup1, tup2);
    }
}
景高杰
2023-03-14

2018年8月:Xcode 9.0(大致相当于开源clang 4.0)仍然没有编译此代码,而g正确地完成了这项工作。

我知道不能使用闪亮的新模板折叠语法很痛苦,但这里有一个基于if constexpr的解决方法,这是我们可以使用的下一个最好的方法。

template <typename T, typename... Ts>
constexpr decltype(auto) multiple_concat(T&& arg, Ts&&... rest) {
    if constexpr (sizeof ...(rest) == 0) {
        return arg;
    }
    else {  // recursively concatenate the tuple
        return arg + multiple_concat(std::forward<Ts>(rest) ...);
    }
}

Clang愉快地编译了这段代码。

施洛城
2023-03-14

因为其他答案没有出来说:代码很好。这是一个长期存在的Clang错误,影响到11个版本。

 类似资料:
  • 考虑以下片段: 在\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\一切工作完美,我得到打印出来的屏幕。 在中,我做了完全相同的操作,希望从参数包中读取。然而,我明白了 我做错了什么?人们会认为事情会完全一样,我只是替换了操作

  • 根据ISO/IEC 14882:2011,我们不能在三元运算符的第二个和第三个操作数中都使用throw表达式: 5.16条件运算符[expr.cond] 2 如果第二个或第三个操作数的类型为 void,则对第二个和第三个操作数执行左值到右值 (4.1)、数组到指针 (4.2) 和函数到指针 (4.3) 的标准转换,并且以下之一应成立: — 第二个或第三个操作数(但不是两个)是抛出表达式 (15.1

  • Bootstrap折叠板插件允许你在网页中用一点点JavaScript以及CSS类切换内容。它是一个灵活的插件,使用少量的类(来自必需的过渡插件),以方便切换行为。 示例 点击下面的按钮,利用类的改变,显示或隐藏另一个元素: .collapse 隐藏内容 .collapsing 在过渡过程中应用到 .collapse.in 显示内容 你可以使用带href属性的链接,或者使用带data-target

  • 使用表达式 例5.1 使用表达式 #!/usr/bin/python # Filename: expression.py length =5 breadth =2 area = length * breadth print'Area is', area print'Perimeter is', 2* (length + breadth) (源文件:code/expression.py) 输出 $

  • 问题内容: 如何使用AngularJS(在模板中)进行三元运算? 最好在html属性中使用一些属性(类和样式),而不是创建和调用控制器的函数。 问题答案: 更新 :Angular 1.1.5添加了一个三元运算符,因此现在我们可以简单地编写 如果使用的是较早版本的Angular,则有两个选择: 上面的项目2创建具有两个属性的对象。数组语法用于选择名称为true的属性或名称为false的属性,并返回关