Я пытаюсь написать какую-то функциональность, в которой мне нужно сохранять различные функции, а затем извлекать типы их аргументов. Поэтому я использую подпись функции в качестве параметра шаблона. Но я получаю несколько неожиданные результаты.
Вот код:
#include <functional>
#include <iostream>
template <class T>
struct foo
{
foo()
{
std::cout << "class T" << std::endl;
}
};
template <class Ret, class Arg>
struct foo<Ret(Arg)>
{
foo()
{
std::cout << "Ret(Arg)" << std::endl;
}
};
template <class T>
void save(std::function<T>)
{
new foo<T>();
}
int main(int argc, char* argv[])
{
std::function<void(void)> someFoo;
save(someFoo);
return 0;
}
Так что если переменная someFoo
это функция с типом void(void)
создает первый шаблон, foo<T>
, Но если я изменю это на void(int)
, чем получаю нужный специализированный шаблон. Это почему?
В C ++, имея void
Аргумент на самом деле такой же, как и вообще без аргумента (кстати, в отличие от C). Так что это будет соответствовать специализации для Ret()
, но это не может соответствовать специализации для Ret(Arg)
,
void(void)
точно так же, как void()
— второй void
не является обязательным и не имеет значения.
Поэтому используется первый шаблон без параметров.