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

C Concepts/SFINAE: clang和MSVC/G使用模板和Concept/SFINAE进行离线函数定义的不同结果

蒙胤
2023-03-14

我正在定义一个类的构造函数,该构造函数约束检查传入迭代器的基础类型与类中定义的node_type的类型等价性,并借助概念或SFINAE。

但是,尝试了一些与is_same的组合

编辑时间:

从GCC 12和Clang 14开始,此错误仍然存在。

> < li>

使用C 20在godbolt上进行如下编码,https://godbolt.org/z/fdqEYxKh8 MSVC/g正常,金属撞击声错误

代码未在下面显示,但在godbolt上使用C 11 SFINAE,MSVC/clang ok,g错误https://godbolt.org/z/7nr7a8jY8

#include <stdio.h>
#include <iterator>
#include <array>
#include <concepts>
#include <cstdlib>

template <typename FPType, std::size_t N>
class PointND {
private:
    std::array<FPType, N> coords_;
};

template <typename FPType, std::size_t N, typename ElemType>
class Tree {
public:

    struct node_type {
        PointND<FPType, N> key;
        ElemType value;
    };
    
    template <std::random_access_iterator RAI>
    requires std::same_as<typename std::iterator_traits<RAI>::value_type, 
                          typename Tree<FPType, N, ElemType>::node_type>
    Tree(RAI, RAI);
};

template <typename FPType, std::size_t N, typename ElemType>
template <std::random_access_iterator RAI> 
requires std::same_as<typename std::iterator_traits<RAI>::value_type, 
                      typename Tree<FPType, N, ElemType>::node_type>
Tree<FPType, N, ElemType>::Tree(RAI begin, RAI end) {
}

e::45:30上的错误:错误:“树”的越线定义

Tree<FPType, N, ElemType>::Tree(RAI begin, RAI end) {

共有1个答案

何嘉运
2023-03-14
匿名用户

在C 11的例子中,添加< code>-fchecking,gcc会说:

<source>:52:51: internal compiler error: canonical types differ for identical types 'std::enable_if<(std::is_same<typename std::iterator_traits<_InputIterator>::iterator_category, std::random_access_iterator_tag>::value && std::is_same<typename std::iterator_traits<_InputIterator>::value_type, typename Tree<FPType, N, ElemType>::node_type>::value), int>' and 'std::enable_if<(std::is_same<typename std::iterator_traits<_InputIterator>::iterator_category, std::random_access_iterator_tag>::value && std::is_same<typename std::iterator_traits<_InputIterator>::value_type, Tree<FPType, N, ElemType>::node_type>::value), int>'
   52 | Tree<FPType, N, ElemType>::Tree(RAI begin, RAI end) {
      |                                                   ^
...
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

gcc未能编译这是一个编译器错误。

我怀疑但无法证明clang在C 20代码上的行为也是一个bug。

有一个简单的解决方法。这些bug与解释名称有关,尤其是在不完整类的上下文中解释嵌套类。因此…将类型移动到命名空间范围:

    < Li > https://god bolt . org/z/ch 7s 8 nkxo(C 11) < Li > https://god bolt . org/z/t 4 cjb 79 ZP(C 20)

 类似资料:
  • 我偶然发现了以下代码。案例在MSVC上产生的结果与在叮当声或gcc上产生的结果不同。也就是说,叮当声 13 和 gcc 11.2 调用 的复制构造函数,而 MSVC v19.29 调用模板化构造函数。我使用的是C 17。 考虑到所有编译器都同意调用模板化构造函数的非派生情况(我认为这是clang和gcc中的一个错误,MSVC是正确的吗?还是我解释错了,叮当/gcc是正确的?任何人都可以对可能发生的

  • 根据enable_if结构的定义: 我想知道怎么做 特别是: 在

  • 以下代码使用clang 3.8.0成功编译,但使用g 7.2.0编译失败(使用编译标志): g错误消息: 哪种编译器行为符合标准?

  • 我一直试图理解C++选择模板的方式。即,考虑以下代码示例: 前两个函数(test1)工作正常(为什么?): 一个常见的错误是声明两个仅在默认模板参数上不同的函数模板。这是非法的,因为默认模板参数不是函数模板签名的一部分,并且用相同的签名声明两个不同的函数模板是非法的。 所以看起来是这样的。但是,我看不出与前两个函数有太大的不同,前两个函数也有默认的模板参数。因此,我们对默认值(test1-work

  • 一般在写C++相关代码的时候,我们总习惯于将类声明和类实现进行分离。也就是说,类的声明一般写在.h文件中,而它的实现一般写在.cpp文件中。但是,在模板类中,这个习惯却要恰恰相反。即:要求模板类的类声明和类实现要都放在头文件,而不能分离。 本文就对模板的这个奇特习惯进行分析。 分离式编译模式 在进行模板特性的讲解之前,首先需要了解一下C++的分离式编译模式。 所谓分离编译模式,就是指:一个程序或者

  • 本文向大家介绍Python函数和模块的使用总结,包括了Python函数和模块的使用总结的使用技巧和注意事项,需要的朋友参考一下 函数和模块的使用 在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解。 $$x_1 + x_2 + x_3 + x_4 = 8$$ 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 $