无法调用模板化的ctor [英] Cannot invoke a templated ctor
问题描述
以下程序在b的定义中产生错误。然而它
编译了模板化的
构造函数的第二种(假定等价的)形式。为什么这两个选择不等同?
模板< class Obj>
struct ptr_to_member
{
typedef void(Obj :: * type)();
};
struct A
{
A(无效(* fn)())
{
}
#if 1
模板< class Obj>
A(typename ptr_to_member< Obj> :: type fn)
{
}
#else
模板< class Obj>
A(void(Obj :: * fn)())
{
}
#endif
};
void foo()
{
}
struct bar
{
void baz()
{
}
};
A a(foo);
A b(& bar :: baz);
The following program produces error at the definition of ``b''''. However it
compiles fine the second (supposedly equivalent) form of the templated
constructor. Why the two alternatives aren''t equivalent ?
template<class Obj>
struct ptr_to_member
{
typedef void (Obj::* type) ();
};
struct A
{
A (void (*fn) ())
{
}
#if 1
template<class Obj>
A (typename ptr_to_member <Obj>::type fn)
{
}
#else
template<class Obj>
A (void (Obj::* fn) ())
{
}
#endif
};
void foo ()
{
}
struct bar
{
void baz ()
{
}
};
A a (foo);
A b (&bar::baz);
推荐答案
" Momchil Velikov" <已经*** @ fadata.bg>在消息中写道
news:87 ************************** @ posting.google.c om ...
"Momchil Velikov" <ve***@fadata.bg> wrote in message
news:87**************************@posting.google.c om...
[...]
模板<类Obj>
A(typename ptr_to_member< Obj> :: type fn)
}
这是一个不可推断的背景。
模板< class Obj>
A(void(Obj :: * fn)())
{
}
[...]
template<class Obj>
A (typename ptr_to_member <Obj>::type fn)
{
}
This is a non-deducible context.
template<class Obj>
A (void (Obj::* fn) ())
{
}
这个上下文是可以推断的。
基本上,如果编译器必须实例化一个匹配
模板参数的类型,然后上下文是不可推导的(
编译器太懒了,无法进行实例化,因为它可以
变得任意复杂,并且在某些情况下可能导致奇怪的
递归)。
Dave
This context is deducible.
Basically, if the compiler has to instantiate a type to match a
template parameter, then the context is non-deducible (the
compiler is too lazy to do the instantiation, since it could
become arbitrarily complex, and probably lead to weird
recursions in some cases).
Dave
>
" David B. Held" < DH *** @ codelogicconsulting.com>在消息中写道
news:bk ********** @ news.astound.net ...
"David B. Held" <dh***@codelogicconsulting.com> wrote in message
news:bk**********@news.astound.net...
" Momchil Velikov" <已经*** @ fadata.bg>在消息中写道
新闻:87 ************************** @ posting.google.c om ...
"Momchil Velikov" <ve***@fadata.bg> wrote in message
news:87**************************@posting.google.c om...
[...]
模板<类Obj>
A(typename ptr_to_member< Obj> :: type fn)
{
}
[...]
template<class Obj>
A (typename ptr_to_member <Obj>::type fn)
{
}
这是一个不可导出的背景。
This is a non-deducible context.
template< class Obj>
A(void(Obj :: * fn)())
{
}
template<class Obj>
A (void (Obj::* fn) ())
{
}
这个上下文是可以推断的。
基本上,如果编译器必须实例化一个匹配
模板参数,然后上下文是不可导入的(
编译器太懒了,无法进行实例化,因为它可能会变得任意复杂,并且在某些情况下可能会导致奇怪的递归)。
戴夫
This context is deducible.
Basically, if the compiler has to instantiate a type to match a
template parameter, then the context is non-deducible (the
compiler is too lazy to do the instantiation, since it could
become arbitrarily complex, and probably lead to weird
recursions in some cases).
Dave
[只是评论]
有趣的是,Visual C ++ 6.0(SP5)是在模板方面还不是一个非常标准的符合
的编译器,它设法推断出上下文。
Chris
[Just a comment]
Interestingly enough Visual C++ 6.0 (SP5) which is not yet a very standard
compliant compiler in terms of templates, manages to deduce the context.
Chris
" Chris Theis" <章************* @ nospam.cern.ch>在消息中写道
news:bk ********** @ sunnews.cern.ch ...
"Chris Theis" <Ch*************@nospam.cern.ch> wrote in message
news:bk**********@sunnews.cern.ch...
[...]
[只是评论]
有趣的是,Visual C ++ 6.0(SP5)在模板方面还不是一个非常符合标准的编译器,它设法推断出上下文。
[...]
[Just a comment]
Interestingly enough Visual C++ 6.0 (SP5) which is not yet a very
standard compliant compiler in terms of templates, manages to
deduce the context.
有趣。请尝试使用此代码:
模板< typename T>
结构标识
{
typedef T type;
};
template< typename T>
void foo(typename identity< T> ::类型)
{
}
int main()
{
int i;
foo(i);
}
Comeau在线提供:
" ComeauTest.c",第15行:错误:没有函数模板的实例" foo"
匹配参数列表
你使用的参数类型是:(int)
foo(i);
^
注意身份元函数是经常明确地使用
压制扣除,所以VC6确实是真的破了,如果它无论如何都要执行
扣除(但我怀疑它不是,
和你的测试代码一起发生了其他事情。)
Dave
Interesting. Please try this code on it:
template <typename T>
struct identity
{
typedef T type;
};
template <typename T>
void foo(typename identity<T>::type)
{
}
int main()
{
int i;
foo(i);
}
Comeau online gives:
"ComeauTest.c", line 15: error: no instance of function template "foo"
matches the argument list
The argument types that you used are: (int)
foo(i);
^
Note that the identity metafunction is often used explicitly to
suppress deduction, so VC6 is truly broken indeed if it performs
the deduction anyway (but I have a suspicion that it doesn''t,
and something else is going on with your test code).
Dave
这篇关于无法调用模板化的ctor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!