Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decltype with template parameter

Below test1.cpp compiles, but test2.cpp does not. The only difference between the two is that I define Handle::add_it within the class declaration in test1.cpp, but outside in test2.cpp.

test1.cpp: g++ test1.cpp -o test1 -std=c++11

#include <iostream>

template<typename B>
class Handle
{
public:
        decltype(B.operator(int)) add_it(int x)
        {
                return b(x);
        }

        B b;
};

struct Add1
{
        int operator()(int x)
        {
                return x + 1;
        }
};

int main()
{
        Handle<Add1> h;
        std::cout << h.add_it(5) << std::endl;
}

test2.cpp: g++ test2.cpp -o test2 -std=c++11

#include <iostream>

template<typename B>
class Handle
{
public:
        decltype(B.operator(int)) add_it(int x);

        B b;
};

template<typename B>
decltype(B.operator(int)) Handle<B>::add_it(int x)
{
        return b(x);
}

struct Add1
{
        int operator()(int x)
        {
                return x + 1;
        }
};

int main()
{
        Handle<Add1> h;
        std::cout << h.add_it(5) << std::endl;
}

Errors

test2.cpp:13:11: error: expected primary-expression before ‘.’ token
 decltype(B.operator(int))
           ^
test2.cpp:13:20: error: expected type-specifier before ‘(’ token
 decltype(B.operator(int))
                    ^
test2.cpp:13:21: error: expected primary-expression before ‘int’
 decltype(B.operator(int))
like image 369
Agrim Pathak Avatar asked Jan 12 '16 09:01

Agrim Pathak


People also ask

What is template argument deduction?

Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.

How do I use decltype in CPP?

In C++11, you can use the decltype type specifier on a trailing return type, together with the auto keyword, to declare a template function whose return type depends on the types of its template arguments.

What is the difference between auto and decltype?

auto is a keyword in C++11 and later that is used for automatic type deduction. The decltype type specifier yields the type of a specified expression. Unlike auto that deduces types based on values being assigned to the variable, decltype deduces the type from an expression passed to it.

Is decltype runtime or compile time?

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


1 Answers

You can amend this by using std::declval:

template<typename B>
class Handle
{
public:
  decltype(std::declval<B>()(int())) add_it(int x) {
    return b(x);
  }

  B b;
};

Live Demo

Or outside the definition of the class:

template<typename B>
class Handle {
public:
  decltype(std::declval<B>()(int())) add_it(int x);
  B b;
};

template<typename B>
decltype(std::declval<B>()(int())) Handle<B>::add_it(int x) {
  return b(x);
}

Live Demo

like image 58
101010 Avatar answered Sep 20 '22 14:09

101010