Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why decltype isn't implicit?

Tags:

c++

c++11

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;
like image 883
p2rkw Avatar asked Jul 27 '14 13:07

p2rkw


People also ask

What is the decltype of a function?

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.

How does decltype work in C++?

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.

What does decltype stand for?

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.

What does decltype return?

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.


1 Answers

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.

  • C++ policy for expressing what you do, and avoid when possible any implicit work by the compiler is IMHO a very good thing. It makes things easier to read, to understand, and to maintain.
  • After all, decltype is only 8 letters

Live demo here.

like image 110
quantdev Avatar answered Oct 16 '22 14:10

quantdev