Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

decltype for class method type

Tags:

c++

decltype

I would like to store return value of class member function in another class.

This seems to work:

class Foo
{
public: 
   Foo(int) {} //non default constructor that hides default constructor
   unspecified_return_type get_value();


};

class Bar
{
    // stores a value returned by Foo::get_value
    decltype(Foo().get_value()) value;
};

However there is a reference to default constructor of class Foo, which may not be defined in some cases. Is there any way to do it without explicitly referring to any constructor?

like image 422
quantum_well Avatar asked Sep 02 '14 10:09

quantum_well


People also ask

What is the return type of decltype?

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 .

Is decltype runtime or compile time?

decltype is a compile time evaluation (like sizeof ), and so can only use the static type.

What is the difference between auto and decltype in C++?

'auto' lets you declare a variable with a particular type whereas decltype lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed 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.


2 Answers

Yup, there is. std::declval was introduced for exactly this reason (not needing to rely on a particular constructor):

decltype(std::declval<Foo>().get_value()) value;
like image 200
jrok Avatar answered Sep 23 '22 06:09

jrok


You could do it with the help of std::declval like the example below:

#include <iostream>
#include <utility>

struct test {
  int val = 10;
};

class Foo {
public:
   test get_value() { return test(); }
};

class Bar {
public:
  using type = decltype(std::declval<Foo>().get_value());
};

int main() {
  Bar::type v;
  std::cout << v.val << std::endl;
}

LIVE DEMO

std::declval<T> converts any type T to a reference type, making it possible to use member functions in decltype expressions without the need to go through constructors.

std::declval is commonly used in templates where acceptable template parameters may have no constructor in common, but have the same member function whose return type is needed.

like image 28
101010 Avatar answered Sep 22 '22 06:09

101010