Decltype declaration type in class

I am trying to use decltype inside a template class as follows:

#include <functional>
template <typename T>
class A
{
    typedef decltype(std::bind(&A::f, std::declval<A>())) some_type;

    void f();
};

This works well, but now I want to add an explicit specialization:

template <>
class A<void>
{
    typedef decltype(std::bind(&A::f, std::declval<A>())) some_type;

    void f();
};

This time g ++ gives an error:

test.cpp:14:33: error: incomplete type 'A<void>' used in nested name specifier

What am I doing wrong? I am using gcc 4.5.

EDIT: if I moved the declaration void f();above typedef, as suggested by Johannes, I get (slightly) different errors:

test.cpp:15:62: error: invalid use of incomplete type 'class A<void>'
test.cpp:13:1: error: declaration of 'class A<void>'
test.cpp:15:62: error:   initializing argument 2 of 'std::_Bind<typename std::_Maybe_wrap_member_pointer<_Tp>::type(_ArgTypes ...)> std::bind(_Functor, _ArgTypes ...) [with _Functor = void (A<void>::*)(), _ArgTypes = {A<void>}, typename std::_Maybe_wrap_member_pointer<_Tp>::type = std::_Mem_fn<void (A<void>::*)()>]'
test.cpp:15:62: error: invalid use of incomplete type 'class A<void>'
test.cpp:13:1: error: declaration of 'class A<void>'
test.cpp:15:62: error:   initializing argument 2 of 'std::_Bind<typename std::_Maybe_wrap_member_pointer<_Tp>::type(_ArgTypes ...)> std::bind(_Functor, _ArgTypes ...) [with _Functor = void (A<void>::*)(), _ArgTypes = {A<void>}, typename std::_Maybe_wrap_member_pointer<_Tp>::type = std::_Mem_fn<void (A<void>::*)()>]'
+3
source share
2 answers

Your order is incorrect. Try to exchange it

template <>
class A<void>
{    
    void f();
    typedef decltype(std::bind(&A::f, std::declval<A>())) some_type;
};

A::f , , f (A::f ++ 0x, A , f , ( ), ). , , f, .

: std::bind. , , A<void>, / std::bind . A<void>.

A, -, declval<A*>(), std::bind -.

, std::function<>, std::bind decltype mess. , , , decltype, , , std::bind. .

+4

std:: bind A (. Johannes), . , some_type, :

#include <functional>

template <typename T>
class A
{
  void f();
  struct some_type_helper
  {
    typedef decltype(std::bind(&A::f, std::declval<A>())) some_type;
  };
};

template <>
class A<void>
{
  void f();
  struct some_type_helper;
};

struct A<void>::some_type_helper
{
  typedef decltype(std::bind(&A::f, std::declval<A>())) some_type;
};
+2

Source: https://habr.com/ru/post/1793497/


All Articles