Clean Up Function Syntax Mess with decltype

Clean Up Function Syntax Mess with decltype

he auto keyword presented here is related to another C++09 proposal: the decltype operator. decltype(e) retrieves the type of the expression e. By combining decltype and auto, you can simplify complex function declarations and reduce maintenance costs. The following sections will show you how to use decltypeto make your functions sing.

Your function consists of a simple return statement. Alas, the manual declaration of a complex return type makes your code brittle and illegible.

Use the decltypeoperator to extract the return type from an expression instead of spelling it out explicitly.

The Point of No return
Suppose you have a function template that returns an iterator designating the end of a vector. The body of such a function is trivial:

return myvector.end();

Similarly, the parameter list of the said function is intuitive:

template  /*return type omitted*/  vector_end( vector& myvector);

Here’s the snag: In C++98 you must specify the return type in every function declaration. To do that, you must check what the type of the expression myvector.end() is, and copy that type to the function’s declaration. After digging into the declarations of all vector::end()overloads, you decide to use the following return type:

template  typename vector::iterator vector_end(vector& myvector){ return myvector.end();}//usage vector vi(5);vector::iterator itr=vector_end(vi);

This code works fine, but it’s not ideal. If the implementer of vector_end() decides to change its parameter to const vector&, the code will break:

template  typename vector::iterator //wrong vector_end(const vector& myvector){ return myvector.end();}vector vi(5);vector::const_iterator itr=vector_end(vi);//error 

The return type of vector_end() is the problem. Since the parameter is const vector&, you must change the return type accordingly to const_iterator:

template  typename vector::const_iterator  vector_end(const vector& myvector){ return myvector.end();}vector vi(5);vector::const_iterator itr=vector_end(vi);//now OK

You already know that the definition of itr can be simplified by using auto:

auto itr=vector_end(vi);

In a similar fashion, you want the return type of vector_end() to be deduced automatically from the expression myvector.end(). This is exactly what decltypedoes.

Type Querying
The delctype operator takes an expression and retrieves its type. In this example, the retrieved type of decltype (myvector.end()) is identical to the return type of myvector.end(). The compiler, not the programmer, traces down the declaration of the particular overloaded vector::end() invoked by myvector.end() and captures its return type. Note that the expression used in a decltype isn’t evaluated; the compiler simply looks up its type. Therefore, you can safely use a function call inside a decltypeto capture the return type of that function. The function itself will not not be invoked. You can now write something like this:

//note: pseudo-codetemplate  decltype(myvector.end())vector_end(const vector& myvector){ return myvector.end();}

Of course, the line containing the decltype will not compile because the compiler hasn’t seen a declaration of myvectorat that point. To solve this problem, C++09 pulls another rabbit from its hat: the return type of a function can be specified after the function’s parameter list:

//note: it's almost workingtemplate  vector_end(const vector& myvector) -> decltype(myvector.end()); //return type

The ->after the function’s parameter list indicates the return type of that function.

There’s one more thing that’s missing here, though. To use the new -> notation, the function must be declared auto:

//now it's readytemplate  auto vector_end(const vector& myvector) ->   decltype(myvector.end());

The above declaration reads: vector_end is a function template taking const vector& and returning whatever the return type of myvector.end()is.

With decltype, any modification of the parameter list propagates automatically to the return type:

template  auto vector_end(vector& myvector) ->    decltype(myvector.end()); //returns vector::iteratortemplate  auto vector_end(string& myvector) ->   decltype(myvector.end()); //string::iteratortemplate  auto vector_end(const vector& myvector) >  decltype(myvector.end()); //vector::const_iterator

In the examples above, the return type is automatically deduced. However, you can use the ->notation for spelling out an explicit return type as well:

auto func(int n) -> bool; 

func() takes a single parameter of type int and returns bool. A more realistic example is a function that returns a pointer to another function:

int handler(); auto get_handler(int signal)-> decltype(handler);

In C++98, the declaration of get_hander()is a monster:

int (*gethandler (int (*pf)()))(); 

A human programmer would unquestionably prefer to use a typedefinstead:

typedef int(*IF)();IF gethandler(int signal);

However, the typedef solution is still problematic. The programmer must examine the declaration of handler(), declare a typedef serving as an alias for that type, and modify that typedef whenever handler()changes its signature.

The Golden Trio
The C++09 auto and decltype keywords delegate the task of querying the return type to the compiler. By moving the return type past the parameter list, you can use decltype(whatever-the-return-statement-contains)to deduce the return type automatically.

The new function declaration syntax consists of the following ingredients:

  • Declare the function as auto.
  • Place -> after the parameter list.
  • Add a decltype expression indicating the return type after the ->.

The decltype facility is already used in the range libraryand other C++09 libraries.

Share the Post:
XDR solutions

The Benefits of Using XDR Solutions

Cybercriminals constantly adapt their strategies, developing newer, more powerful, and intelligent ways to attack your network. Since security professionals must innovate as well, more conventional endpoint detection solutions have evolved

AI is revolutionizing fraud detection

How AI is Revolutionizing Fraud Detection

Artificial intelligence – commonly known as AI – means a form of technology with multiple uses. As a result, it has become extremely valuable to a number of businesses across

AI innovation

Companies Leading AI Innovation in 2023

Artificial intelligence (AI) has been transforming industries and revolutionizing business operations. AI’s potential to enhance efficiency and productivity has become crucial to many businesses. As we move into 2023, several

data fivetran pricing

Fivetran Pricing Explained

One of the biggest trends of the 21st century is the massive surge in analytics. Analytics is the process of utilizing data to drive future decision-making. With so much of

kubernetes logging

Kubernetes Logging: What You Need to Know

Kubernetes from Google is one of the most popular open-source and free container management solutions made to make managing and deploying applications easier. It has a solid architecture that makes

ransomware cyber attack

Why Is Ransomware Such a Major Threat?

One of the most significant cyber threats faced by modern organizations is a ransomware attack. Ransomware attacks have grown in both sophistication and frequency over the past few years, forcing

data dictionary

Tools You Need to Make a Data Dictionary

Data dictionaries are crucial for organizations of all sizes that deal with large amounts of data. they are centralized repositories of all the data in organizations, including metadata such as