2

I am confused of the type of decltype a function. It is neither a function pointer nor functor. How can I use it? And why the full template specialization here does not require const qualifier.

class SomeClass
{
public:
    template <typename T>
    void insideTemplateMethod(const T & value)
    {
    }
};
template
void SomeClass::insideTemplateMethod<decltype(std::hex)>(decltype(std::hex) & ); // no need to specify const

template
void SomeClass::insideTemplateMethod<int>(int &); // error, must specify const

int main(void)
{}

if I remove the &, it then complains that

error: template-id 'insideTemplateMethod<std::ios_base&(std::ios_base&)>' for 'void SomeClass::insideTemplateMethod(std::ios_base& (*)(std::ios_base&))' does not match any template declaration"

Look, the decltype(std::hex) in parameter field is deducted to std::ios_base& (*)(std::ios_base&), whereas it is deducted to std::ios_base&(std::ios_base&) in the parameter of template.

Could you please help me understand it?

Evg
  • 25,259
  • 5
  • 41
  • 83
Wubin Ouyang
  • 777
  • 1
  • 7
  • 9

2 Answers2

2

std::hex is a function, with the following declaration (see cppreference):

std::ios_base& hex( std::ios_base& str );

If T is the type of this function, namely std::ios_base&(std::ios_base&), then because it is a function type, const T is the same as T. This is why the explicit instantiation definition can be written without the const.

Note that if you remove the & from the explicit instantiation definition, then the function parameter type decltype(std::hex) undergoes the standard transformation from a function type to a function pointer type. This is why you are seeing (*) in the error message.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Just to clarify for the OP: Without the &, the function type "decays". That is a standard process from C++ where arrays decay to pointers and functions to function pointers. – LeDYoM Dec 02 '19 at 21:09
0

To cite the standard:

The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. [ Note: A function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types. — end note ] [ Example:

typedef void F();
struct S {
    const F f;        // OK: equivalent to: void f();
};

— end example ]

Evg
  • 25,259
  • 5
  • 41
  • 83