On Wed, Dec 15, 2010 at 10:57 AM, Jonathan Wakely <jwakely.gcc@xxxxxxxxx> wrote: > Please reply on the mailing list, I don't want to give you private C++ > lessons. Thanks. > > On 15 December 2010 02:20, zhang qingshan wrote: >> On Tue, Dec 14, 2010 at 5:11 PM, Jonathan Wakely wrote: >>> On 14 December 2010 07:26, zhang qingshan wrote: >>>> std 8.3.2/1 says >>>> >>>> Cv-qualified references are ill-formed except when the cv-qualifiers >>>> are introduced through >>>> the use of a typedef (7.1.3) or of a template type argument (14.3), in >>>> which case the cv-qualifiers are ignored >>>> >>>> following code is tested at GCC 4.5.0. >>>> >>>> template <typename T> >>>> void fun(const T&t); >>>> void foo(); >>>> void Test() { >>>> fun(foo); >>>> } >>>> >>>> It seems that, fun should be resolved as void (void (&)()), as const >>>> is ignore here. >>> >>> No. > > Const is not ignored here because of 8.3.2/1, because you do not have > a const-qualified reference. > > Please read the FAQs I sent you, maybe you are still confused about > what "const T&" means. > Ok, all my examples are not relative with qulifier reference. In fact, I can fully understand the difference between const T& and T&const. It acts the same sematic as const T* and T*const, AFAIK. Sadly, I cannot understand what the situation would be if T is replaced by function. When the template argument substitudition happens, T --> void (), const T --> void (), as it is a const qualifier function, which const is ignore. finally, reference apply for this type descriptor. const T& --> void(&)(). I believe that, I have missed something here. >> if it is resolved as void(void(const&)()), I cannot compile the >> following code with GCC. >> void fun(void (const &f)()) >> { >> } > > That syntax is not valid. > > Maybe you want: > > typedef void (func_type)(); > > void fun (const func_type& f) > { > } > > That would be a reference to a const function, but see 8.3.5/5 - there > are no cv-qualified function types, so the const is ignored. But > that's a different rule to the one you keep quoting from 8.3.2/1. > > Const is ignored on references, but that's not what your example > shows. Your example adds a const to a function type. Your example is > not related to 8.3.2/1 > > In the error message you got, it shows "void (const&)()" but that is > NOT a const-qualified reference, it's a const-qualified function, so > the const is ignored because of 8.3.5/5. You can demonstrate that by > providing a specialization without the const, which resolves the link > error: > > template <typename T> > void fun(const T&t); > > typedef void(func_type)(); > template<> > void fun<func_type>(func_type&) { } > > void foo(); > void Test() { > fun(foo); > } > > This shows that "void (const&)()" and "void (&)()" are equivalent. > That's still nothing to do with 8.3.2/1 > > THIS would be a const qualified reference introduced by a template > type argument, so the const would be ignored: > > template<typename T> > void f(const T); > > void Test() { > int i = 0; > f<int&>(i); > } > > Here the template parameter is "int&" so the function argument type is > "int& const" but that forms a cv-qualified reference, so the const is > ignored, and the type of the template function specialization is > "f<int&>(int&)" Thanks for your example and detail explain about the cv-qualified reference and cv-qualified function.