- This code compiles fine in clang without any change but in g++ it throws an error about the packed struct field cannot be bound to a reference.
- Also
make_pair(packed_bitfield, packed_bitfield)
gives similar compile error. - If the code which calls universal reference function
f
can be altered, I canpass f(static_cast<const int &>(x.i)) or as_const(x.i)
to universal reference function. - The const creates a temporary which is aligned. But in many cases i cannot change the calling code.
In what cases will my fix fail to work ? Am i missing any corner cases ?
#include<iostream>
using namespace std;
template<typename T>
int f(T&& args) {
return args;
}
struct X {
char c;
unsigned int i;
} __attribute__((packed));
int main() {
X x;
x.i = 3;
cout <<"x.i= "<<f(x.i)<<endl;
return 0;
}
test3.cpp: In function ‘int main()’:
test3.cpp:16:22: error: cannot bind packed field ‘x.X::i’ to ‘unsigned int&’
16 | cout <<"x.i= "<<f(x.i)<<endl;
| ~~^
To fix this add const T && ref
universal ref and another overload template function f(const L& arg)
which is only instantiated if L is a non rvalue reference. The new code becomes
template<typename T>
expr_lhs<const T> f(const T && head)
{
cout <<"in const universal ref ";
return expr_lhs<const T>(forward<const T>( head )) ;
}
template<typename T,typename enable_if< !is_rvalue_reference<T>::value , void >::type* = nullptr >
int f(const T &head){
cout <<"in const non rvalue ref ";
return 17;
}
compiles and produces output
- 5= in const universal ref 5
- temp rvalue = in const universal ref 0
- rvalue = in const universal ref 3
- i = in const non rvalue ref 17
- x.i= in const non rvalue ref 17
Aucun commentaire:
Enregistrer un commentaire