位字段在模板的重载分辨率 [英] bit-field in overload resolution for template

查看:148
本文介绍了位字段在模板的重载分辨率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都知道为什么第一个程序编译,但第二个没有?唯一的区别是第一个使用正常功能,第二个使用模板功能。为什么模板和非模板函数的位字段上的过载解析的行为不同?

Anyone knows why the first program compiles but second one doesn't? The only difference is that the first one uses normal function but the second one uses template function. Why the overload resolution behaves differently on bitfield for template and non-template function?

回答时请参考标准中的段落。非常感谢。

Please refer to paragraphs in standard when answering. Thanks.

a.cpp

struct X {
  int x : 20;
  int y : 12;
};

void f(const int& x) {}

void f(int&& x) {}

int main() {
  X x;
  f(x.x);
}

b.cpp

struct X {
  int x : 20;
  int y : 12;
};

template <typename T>
void f(T&& x) {}

template <typename T>
void f(const T& x) {}

int main() {
  X x;
  f(x.x);
}

编译器错误:

[hidden]$ g++ -v 2>&1 | tail -n 1
gcc version 4.7.2 20120921 (Red Hat 4.7.2-2) (GCC)
[hidden]$ clang++ -v 2>&1 | head -n 1
clang version 3.3
[hidden]$ g++ -std=c++11 a.cpp
[hidden]$ g++ -std=c++11 b.cpp
b.cpp: In function ‘int main()’:
b.cpp:14:8: error: cannot bind bitfield ‘x.X::x’ to ‘int&’
[hidden]$ clang++ -std=c++11 a.cpp
[hidden]$ clang++ -std=c++11 b.cpp
b.cpp:14:5: error: non-const reference cannot bind to bit-field 'x'
  f(x.x);
    ^~~
b.cpp:2:7: note: bit-field is declared here
  int x : 20;
      ^
1 error generated.


推荐答案

错误很清楚, >非const引用到位字段 [class.bit] / 3

The error is quite clear, you cannot take non-const references to bitfields. [class.bit]/3:


不应用于位字段,因此没有指向位字段的指针。非const引用不应该绑定到位字段(8.5.3)。 [注意:如果const T&是引用位字段的左值,引用绑定到临时初始化以保存位字段的值;该引用不直接绑定到位域。见8.5.3。 -end note]

The address-of operator & shall not be applied to a bit-field, so there are no pointers to bit-fields. A non-const reference shall not be bound to a bit-field (8.5.3). [ Note: If the initializer for a reference of type const T& is an lvalue that refers to a bit-field, the reference is bound to a temporary initialized to hold the value of the bit-field; the reference is not bound to the bit-field directly. See 8.5.3. —end note ]

重载解析的原因与通用参考有关。参考折叠规则和模板使得:

The reason overload resolution behaves differently has to do with Universal References. Reference collapsing rules and templates make this:

template <typename T>
void f(T&& x) {}

导致<$ c $应用于非常数值 <$ c时,应将 T&&&& 推导为 int& $ c> int ,这是 xx 的情况。在这种特殊情况下,你会看到:

result in T&& to be deduced as int& when applied to a non-const lvalue int, which is the case for x.x. In that particular case, you are left with:

void f(int& x){}
void f(int const& x){}

,第一个, code> f(T& x),可以清楚地看出它是比后者更好的匹配。

and the first one, the one obtained from reference collapsing rules on f(T&& x), it can be clearly seen to be a better match than the later one.

这篇关于位字段在模板的重载分辨率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆