I'm having trouble with auto and decltype.
void f(const vector<int>& a, vector<float>& b)
{
typedef decltype(a[0]*b[0]) Tmp;
for (int i=0; i < b.size(); ++i) {
auto p0 = new auto(a[i]*b[i]);
auto p1 = new decltype(a[i]*b[i]);
*p0=a[i]*b[i];
*p1=a[i]*b[i];
cout<<*p0<<endl;
cout<<*p1<<endl;
delete p0;
delete p1;
}
}
int main()
{
vector<float>vec2;
vec2.push_back(2.0);
vector<int>vec1;
vec1.push_back(5);
return 0;
}
The above code runs well in GCC4.7. Could I use 'new auto(a[0]*b[0])' to allocate memory for the type of a[0]*b[0]? And I can not distinguish the difference between decltype and auto in this case.
The difference is that this:
new auto(a[i]*b[i]);
is allocating an object of whatever type a[i]*b[i]
is, and initializes the object with that value. That is, the parentheses are an initializer. Whereas using decltype:
new decltype(a[i]*b[i]);
allocates an object of the same type, but there is no initializer. The object is default initialized.
Basically decltype(...)
is treated as a type, while auto
specifies a type to be deduced from an intializer.
Since new
shouldn't be used except in special cases, if for some reason these semantics are needed they'd properly be written something like this:
template<typename T, typename... Args> T make_unique(Args &&...args) {
return std::unique_ptr<T>{std::forward<Args>(args)...};
}
template<typename T> T make_unique_auto(T &&t) {
return std::unique_ptr<T>{std::forward<T>(t)};
}
// new auto(a[i]*b[i])
auto p1 = make_unique_auto(a[i]*b[i]);
// new decltype(a[i]*b[i])
auto p2 = make_unique<decltype(a[i]*b[i])>();
Furthermore, if one gets used to using C++11 uniform initialization universally the and if one stops using parentheses for initialization then eventually the parentheses used with decltype
cease to look to the programmer like an initializer.
For this reason and others, I think it would be good for a 'modern' C++11 style to include a rule that one should always use braces and never use parentheses for initialization. (And constructors that cannot be called except with parentheses, e.g. std::vector<int>(int,int);
, should be avoided; don't create new ones and don't use legacy ones.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With