此代码有效吗?适用于gcc,不适用于clang

吕韦拉

以下最少代码在g ++上编译,但不会在clang ++上编译:

template<class T>
T operator*(float a, const T& b)
{
    return b * a;
}

struct A{
    A operator*(float b) const
    {
        A a;
        return a;
    }
};

int main()
{
    A a;
    2.0f * a;
}

这是我得到的错误:

$ clang++ test.cpp 
test.cpp:2:3: error: overloaded 'operator*' must have at least one parameter of
      class or enumeration type
T operator*(float a, const T& b)
  ^
test.cpp:4:11: note: in instantiation of function template specialization
      'operator*<float>' requested here
        return b * a;
                 ^
test.cpp:18:10: note: in instantiation of function template specialization
      'operator*<A>' requested here
    2.0f * a;
         ^
1 error generated.

Clang版本3.5。此代码有效吗?Clang有bug吗?

玉米秸秆

2.0f * a;实例化::operator*<A>在该函数中,我们有表达式b * a,如果您查看(简化的)类型,则该表达式A * float此时,编译器需要做出选择。应该*是全局函数::operator*<float>(因为右手参数是float),还是应该A::operator*对于我们人类来说,很明显应该是A::operator*,但是从编译器的角度来看,目前尚不清楚。

那么编译器做什么?它首先试图找到所有的operator*,其功能可以被用来(之后,它试图确定究竟使用哪一个)。其中的一个operator*,其功能可以被用来为::operator*<float>但是等等,是什么::operator*<float>float *(float, const float&)啊!而且我们不能那样做!您不能重载原始类型的运算符(如果您重载int +(int, int),请想象一下混乱,以便您1 + 2做的事情与每个人都期望的完全不同)。

此时,程序格式不正确。编译器甚至尝试实例化的事实::operator*<float>使整个程序无效。所以,我们能做些什么?告诉编译器确切的操作:

template<class T>
T operator*(float a, const T& b)
{
    // This prevents the compiler from instantiating ::operator*<float>
    return b.operator*(a);

    // The above is meant to illustrate how the fix needs to work: it needs
    // to avoid instantiating ::operator*<float>. Other methods can be used
    // (like SFINAE) that might be more elegant (check out Walter's answer
    // in the duplicate: https://stackoverflow.com/a/18596809/1287251), but
    // in the end any solution used must avoid ::operator*<float>.
}

struct A{
    A operator*(float b) const
    {
        A a;
        return a;
    }
};

int main()
{
    A a;
    2.0f * a;
}

简而言之,要回答这个问题:不,代码无效。您必须防止编译器尝试实例化::operator*<float>

这是通过在评论@dyp解释,并通过@TemplateRex在重复的问题但是,在理解它们的含义之前,我不得不多次阅读他们的回答。我试图简化此答案中的内容。如果可以改善,请告诉我!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Clang编译有效,而gcc不适用于钻石继承

来自分类Dev

适用于gcc但不适用于clang的汇编代码

来自分类Dev

代码不适用于“ createElement”,但是如果先前创建的元素有效

来自分类Dev

使用enable_if选择特征-适用于clang,但不适用于gcc

来自分类Dev

是什么使此代码适用于 Y 轴而不适用于 X 轴?

来自分类Dev

为什么此代码不适用于svg元素?

来自分类Dev

此源代码不适用于Firefox

来自分类Dev

动态数组运行时错误-代码有效,但不适用于较大的输入值| 怎么解决?

来自分类Dev

Haskell,函数在使用数字时有效,但不适用于变量

来自分类Dev

JSON.parse不适用于有效的json

来自分类Dev

Python PIL JPEG支持在Heroku上有效,但不适用于本地

来自分类Dev

Perl DBI连接有效,但不适用于Catalyst

来自分类Dev

.htaccess重定向在OSX本地有效,但不适用于Windows XAMPP

来自分类Dev

file_get_contents(JSON)不适用于有效的URL

来自分类Dev

列表理解有效,但不适用于循环-为什么?

来自分类Dev

带参数的角度“懒惰”路由在本地有效,但不适用于生产

来自分类Dev

命令在终端上有效,但不适用于Kotlin

来自分类Dev

Haskell,函数在使用数字时有效,但不适用于变量

来自分类Dev

Ruby chmod有效,但不适用于一个名为“ js /”的目录

来自分类Dev

Ping主机名有效,但ssh不适用于本地计算机

来自分类Dev

ul 选择器有效,但不适用于 ul 的类

来自分类Dev

适用于iOS应用的有效UI样式

来自分类Dev

AngularJS代码不适用于NodeJS

来自分类Dev

代码不适用于长回文

来自分类Dev

代码不适用于JS Fiddle

来自分类Dev

代码不适用于长回文

来自分类Dev

代码不适用于大量

来自分类Dev

基本代码不适用于jQuery

来自分类Dev

Angular代码不适用于Express

Related 相关文章

  1. 1

    Clang编译有效,而gcc不适用于钻石继承

  2. 2

    适用于gcc但不适用于clang的汇编代码

  3. 3

    代码不适用于“ createElement”,但是如果先前创建的元素有效

  4. 4

    使用enable_if选择特征-适用于clang,但不适用于gcc

  5. 5

    是什么使此代码适用于 Y 轴而不适用于 X 轴?

  6. 6

    为什么此代码不适用于svg元素?

  7. 7

    此源代码不适用于Firefox

  8. 8

    动态数组运行时错误-代码有效,但不适用于较大的输入值| 怎么解决?

  9. 9

    Haskell,函数在使用数字时有效,但不适用于变量

  10. 10

    JSON.parse不适用于有效的json

  11. 11

    Python PIL JPEG支持在Heroku上有效,但不适用于本地

  12. 12

    Perl DBI连接有效,但不适用于Catalyst

  13. 13

    .htaccess重定向在OSX本地有效,但不适用于Windows XAMPP

  14. 14

    file_get_contents(JSON)不适用于有效的URL

  15. 15

    列表理解有效,但不适用于循环-为什么?

  16. 16

    带参数的角度“懒惰”路由在本地有效,但不适用于生产

  17. 17

    命令在终端上有效,但不适用于Kotlin

  18. 18

    Haskell,函数在使用数字时有效,但不适用于变量

  19. 19

    Ruby chmod有效,但不适用于一个名为“ js /”的目录

  20. 20

    Ping主机名有效,但ssh不适用于本地计算机

  21. 21

    ul 选择器有效,但不适用于 ul 的类

  22. 22

    适用于iOS应用的有效UI样式

  23. 23

    AngularJS代码不适用于NodeJS

  24. 24

    代码不适用于长回文

  25. 25

    代码不适用于JS Fiddle

  26. 26

    代码不适用于长回文

  27. 27

    代码不适用于大量

  28. 28

    基本代码不适用于jQuery

  29. 29

    Angular代码不适用于Express

热门标签

归档