Why decltype can't be implicitly added to an expression when type was expected?
template <class X, class Y, class Z>
auto foo(X x, Y y, Z z){
std::vector<decltype(x+y*z)> values; // valid in c++11/c++14
//std::vector<x+y*z> values; // invalid
values.push_back(x+y*z);
return values; // type deduced from expression - OK
}
In c++14 compilers will able to deduce function return type based on return expressions. Why this can't be extended to any 'expression -> type' conversion?
The same apply to declval, why I have to write:
std::vector<decltype(declval<X>() + declval<Y>() * declval<Z>())> values;
instead of:
std::vector<X+Y*Z> values;
If the expression parameter is a call to a function or an overloaded operator function, decltype(expression) is the return type of the function. Parentheses around an overloaded operator are ignored. If the expression parameter is an rvalue, decltype(expression) is the type of expression.
In the C++ programming language, decltype is a keyword used to query the type of an expression. Introduced in C++11, its primary intended use is in generic programming, where it is often difficult, or even impossible, to express types that depend on template parameters.
Software Engineering C++ Decltype stands for declared type of an entity or the type of an expression. It lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed expression.
decltype returnsIf what we pass to decltype is the name of a variable (e.g. decltype(x) above) or function or denotes a member of an object ( decltype x.i ), then the result is the type of whatever this refers to.
If implicit addition of decltype
would be allowed, some very common templates would become ambiguous, or even impossible to express.
Consider the following example :
struct tp
{
template<typename T>
void foo() { cout << "Type parameter\n"; }
template<int Value>
void foo() { cout << "Value parameter\n"; }
};
int main()
{
const int x = 1;
const int y = 2;
const int z = 3;
tp t1;
t1.foo<x*y+z>();
t1.foo<decltype(x*y+z)>(); // Oops ! different version of foo()
t1.foo<int>();
return 0;
}
Output:
Value parameter
Type parameter
Type parameter
If decltype
is implicitly added to t1.foo<x*y+z>();
, the wrong version of foo()
is called.
decltype
is only 8 lettersLive demo here.
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