使用模板参数进行Decltype

Agr*_*hak 6 c++ templates decltype c++11

test1.cpp下面编译,但test2.cpp不编译.两者之间的唯一区别是我Handle::add_ittest1.cpp中的类声明中定义,但在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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

错误

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))
Run Code Online (Sandbox Code Playgroud)

101*_*010 4

您可以使用以下方法修改此设置std::declval

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

  B b;
};
Run Code Online (Sandbox Code Playgroud)

现场演示

或者在类的定义之外:

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);
}
Run Code Online (Sandbox Code Playgroud)

现场演示