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

clang失败,但g成功使用强制转换来赋值中的const无关类型运算符

葛胡媚
2023-03-14

这里有一个简短的示例,它用lemon表示clang,但对编译器行为中的g差异有效,从而再现了这种“不可行的转换”。

#include <iostream>

struct A { 
    int i; 
};

#ifndef UNSCREW_CLANG
using cast_type = const A;
#else 
using cast_type = A;
#endif

struct B {
    operator cast_type () const {
        return A{i};
    }
    int i;
}; 

int main () { 
    A a{0};
    B b{1};

#ifndef CLANG_WORKAROUND
    a = b;
#else    
    a = b.operator cast_type ();
#endif    

    std::cout << a.i << std::endl;    

    return EXIT_SUCCESS;
}

住在戈博尔特家

g(4.9,5.2)默默编译;而clang(3.5,3.7)编译它

如果

using cast_type = A;

using cast_type = const A;
// [...] 
a = b.operator cast_type ();

使用,但不与默认

using cast_type = const A;
// [...] 
a = b; 

在这种情况下,clang(3.5)责备a=b

testling.c++:25:9: error: no viable conversion from 'B' to 'A'
    a = b;
        ^
testling.c++:3:8: note: candidate constructor (the implicit copy constructor) 
not viable:
      no known conversion from 'B' to 'const A &' for 1st argument
struct A { 
       ^
testling.c++:3:8: note: candidate constructor (the implicit move constructor) 
not viable:
      no known conversion from 'B' to 'A &&' for 1st argument
struct A { 
       ^
testling.c++:14:5: note: candidate function
    operator cast_type () const {
    ^
testling.c++:3:8: note: passing argument to parameter here
struct A { 

关于2011¹标准:clang拒绝默认代码是正确的还是接受它是正确的?

注:这不是关于cast\u类型上的const限定符是否有意义的问题。这是关于哪个编译器的工作符合标准,并且仅限于此。

¹2014年在这里不应该有什么不同。

编辑:

请不要用通用c标记重新标记。首先,我想知道哪些行为符合2011年的标准,并保持委员会的敬业精神,不破坏现有标准(

共有1个答案

伍胡媚
2023-03-14

所以看起来这被这个clang bug报告覆盖了右值重载隐藏了const左值?它有以下示例:

struct A{};
struct B{operator const A()const;};
void f(A const&);
#ifdef ERR
void f(A&&);
#endif
int main(){
  B a;
  f(a);
}

它失败了,错误与OP的代码相同。理查德·史密斯最后说:

更新:我们选择“f(A)”是正确的

  struct A {};
  struct B { operator const A(); } b;
  A &&a = b;

这里,[dcl.init.ref]p5 bullet 2 bullet 1 bullet 2不适用,因为[over.match.ref]p1找不到候选转换函数,因为“A”与“const A”不兼容引用。因此我们进入[dcl.init.ref]p5 bullet 2 bullet 2,从“b”复制初始化a类型的临时文件,并将引用绑定到该临时文件。我不确定在这个过程中我们哪里出错了。

但是,由于1604年的缺陷报告,我们又提出了另一条评论:

DR1604更改了规则,以便

 A &&a = b;

现在是格式错误的。所以我们现在拒绝初始化是正确的。但这仍然是一个糟糕的答案;我再次刺激了CWG。我们可能应该丢弃f(A

因此,看起来clang在今天的标准语言基础上做了正确的事情,但它可能会改变,因为至少clang团队似乎不同意这是正确的结果。因此,这可能会导致缺陷报告,我们必须等到问题解决后才能得出最终结论。

更新

看起来缺陷报告2077是基于这个问题提交的。

 类似资料:
  • 强制类型转换 隐式类型转换:隐式类型转换又称为自动类型转换,隐式类型转换可分为三种:算术转换、赋值转换和输出转换。 显式类型转换:显式类型转换又称为强制类型转换,指的是使用强制类型转换运算符,将一个变量或表达式转化成所需的类型,这种类型转换可能会造成数据的精度丢失。 数据有不同的类型,不同类型数据之间进行混合运算时必然涉及到类型的转换问题。 转换的方法有两种: 自动转换(隐式转换):遵循一定的规则

  • 我正在学习颤振(主要来自Youtube) 为什么我们需要在赋值运算符后面使用关键字,因为我们已经将其设置为

  • 问题内容: 直到今天,我还以为例如: 只是以下方面的捷径: 但是,如果我们尝试这样做: 然后;将不会编译,但;会编译良好。 这是否意味着实际上;是类似这样的捷径 ? 问题答案: 与这些问题一样,JLS保留了答案。在这种情况下,第1.5.26.2节“复合赋值运算符”。摘录: 形式的复合赋值表达式等效于,其中T是的类型,不同之处在于该表达式E1仅被评估一次。 §15.26.2中引用的示例 以下代码正确

  • C++ 运算符 强制转换运算符是一种特殊的运算符,它把一种数据类型转换为另一种数据类型。强制转换运算符是一元运算符,它的优先级与其他一元运算符相同。 大多数的 C++ 编译器都支持大部分通用的强制转换运算符: (type) expression 其中,type 是转换后的数据类型。下面列出了 C++ 支持的其他几种强制转换运算符: const_cast<type> (expr): const

  • 问题内容: 这是我的代码的一部分: 这是Tumblr API的JSON的一部分: 等等。 这是我的错误: 在这行上: 我不明白为什么。我对JSON和iOS还是很陌生,但是“响应”对我来说就像字典,我不知道为什么它是NSArray,我也不知道如何解决这个问题。任何帮助将不胜感激。 这不是重复的,因为其他帖子没有帮助我解决此问题。 问题答案: 错误消息说 无法将 实际 类型NSDictionary强制

  • 本文向大家介绍C#中的自动类型转换和强制类型转换,包括了C#中的自动类型转换和强制类型转换的使用技巧和注意事项,需要的朋友参考一下 前面已经认识了不同的数据类型,你们有没有尝试过让不同的数据类型进行运算呢? 运行结果是:1 我们把一个整型的变量赋值给了一个浮点型的变量,可以正常的输出,如果我们把一个浮点型的变量赋值给一个整型的变量呢? 这样就会报错。 为什么呢?因为我们之前说过,变量就像一个容器,