шаблон и decltype для void f (int) - PullRequest
3 голосов
/ 19 июня 2020

Я учусь писать свои собственные черты, используя только C ++ 11, заимствуя std::true_type и std::false_type.

Я создал следующую черту:

#include <iostream>

template <typename F>
struct is_farg1: std::false_type {};

template <typename R, typename A>
struct is_farg1<R (*)(A)> : std::true_type {};

Теперь рассмотрим программа, включающая указанную выше черту и следующий код:

void f(int) {}

int main() {
    std::cout << "is_farg1<decltype(f)>  : " << is_farg1<decltype(f)>::value << std::endl;
    std::cout << "is_farg1<void(*)(int)> : " << is_farg1<void(*)(int)>::value << std::endl;

    return 0;
}

Она выдает следующий результат:

is_farg1<decltype(f)>  : 0
is_farg1<void(*)(int)> : 1

Мои вопросы:

  1. Почему is_farg1<void(*)(int)>::value равно true, а is_farg1<decltype(f)>::value возвращено false?
  2. Если моя характеристика написана неправильно, как я могу проверить, имеет ли данная функция один и только один аргумент, чтобы я мог также использовать decltype(f) ?

1 Ответ

6 голосов
/ 19 июня 2020

Потому что decltype(f) дает точный тип функции (например, void(int)), но не тип указателя функции (например, void(*)(int)). Когда decltype используется для объекта,

Если аргумент не заключен в скобки id-выражение или доступ к члену класса без скобок выражение, затем decltype дает тип объекта , названного этим выражением.

Вы можете добавить другую специализацию для типа функции, например

template <typename R, typename A>
struct is_farg1<R (A)> : std::true_type {};

LIVE

Или проверьте тип как указатель на функцию, например

is_farg1<decltype(f)*>::value
//                  ^

// or
is_farg1<decltype(&f)>::value
//                ^

LIVE

...