[英]decltype in class template specialization
I am trying to use decltype inside a template class as follows: 我试图在模板类中使用decltype,如下所示:
#include <functional>
template <typename T>
class A
{
typedef decltype(std::bind(&A::f, std::declval<A>())) some_type;
void f();
};
That works fine, but now I'd like 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: 这次g ++给出了一个错误:
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.
我正在使用gcc 4.5。
EDIT: If I move the declaration of void f();
编辑:如果我移动
void f();
的声明void f();
to above the typedef, as suggested by Johannes, I get (slightly) different errors: 如Johannes所建议的那样,在typedef之上,我得到(稍微)不同的错误:
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>::*)()>]'
Your order is wrong. 你的订单错了。 Try exchanging it
尝试交换它
template <>
class A<void>
{
void f();
typedef decltype(std::bind(&A::f, std::declval<A>())) some_type;
};
In the primary template, the name A::f
was dependent and the compiler delayed lookup to a point where f
was declared ( A::f
is not really dependent in C++0x anymore, since A
refers to the current instantiation and therefor f
to a member of the current instantiation, but as there is a loophole in the current specification (it has to do with dependent base classes), the compiler delayed the lookup nontheless). 在主模板中,名称
A::f
是依赖的,并且编译器将查找延迟到声明f
的点( A::f
实际上不再依赖于C ++ 0x,因为A
指的是当前实例化,因此f
到当前实例化的成员,但由于当前规范中存在漏洞(它与依赖的基类有关),编译器仍延迟了查找)。 In the explicit specialization, the name is not dependent and lookup is done immediately, which is the reason you need to declare f
before referring to it. 在显式特化中,名称不依赖,并且立即执行查找,这是您在引用它之前需要声明
f
的原因。
Edit: You are wrongly using std::bind
. 编辑:您错误地使用
std::bind
。 The second argument you give is of type A<void>
, which will be copied/moved by std::bind
into its created call wrapper object. 您给出的第二个参数是类型
A<void>
,它将被std::bind
复制/移动到其创建的调用包装器对象中。 This requires a complete type A<void>
. 这需要一个完整的类型
A<void>
。
If you want to merely pass a reference to A
on which the member function is called, you can pass a declval<A*>()
, which the std::bind
mechanism equally detects as magical first argument to a member pointer invocation. 如果您只想传递对其中调用成员函数的
A
的引用,则可以传递一个declval<A*>()
, std::bind
机制同样将其视为成员指针调用的神奇第一个参数。
But it seems to me you want to look into std::function<>
, instead of doing this std::bind
and decltype
mess. 但在我看来,你想要研究
std::function<>
,而不是做这个std::bind
和decltype
混乱。 After all you have a powerful toolset given, but by using this doubtful decltype
expression, you throw away all the genericity the Standard library gives you and restrict yourself to use of that single std::bind
expression. 毕竟你有一个强大的工具集,但是通过使用这个令人怀疑的
decltype
表达式,你抛弃了标准库给你的所有通用性,并限制自己使用那个单独的std::bind
表达式。 That's no good. 那不好。
std::bind requires A as a complete type (see answer by Johannes) and therefore you cannot use it at this point. std :: bind需要A作为完整类型(请参阅Johannes的回答),因此您不能在此时使用它。 As a workaround, if you encapsulate the some_type this will compile :
作为一种解决方法,如果你封装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;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.