В чем принципиальная разница между этими двумя вариационными функциями? - PullRequest
2 голосов
/ 18 августа 2011

Я был разочарован простой функцией шаблона variadic:

constexpr size_t num_args () {
    return 0;
}

template <typename H, typename... T>
constexpr size_t num_args () {
    return 1 + num_args <T...> ();
}

int main () {
    std :: cout << num_args <int, int, int> ();
}

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

template <typename T, typename... Args> void foo (T, Args...);

template <typename... Args> void foo (int, Args...);

void foo () {}

template <typename... Args>
void foo (int x, Args... args)
{
    std :: cout << "int:" << x;
    foo (args...);
}

template <typename T, typename... Args>
void foo (T x, Args... args)
{
    std :: cout << " T:" << x;
    foo (args...);
}

foo (int (123), float (123)); // Prints "int:123 T:123.0"

Кажется, что оба используют один и тот же языковой механизм, но почему первый плох, а второй хорош?

Ответы [ 2 ]

4 голосов
/ 18 августа 2011

Разница в том, что первая функция

constexpr size_t num_args () {
    return 0;
}

не является шаблоном, поэтому ее никогда нельзя так назвать

num_args <T...> ();
0 голосов
/ 19 августа 2011

Я начинаю думать, что разница в том, что

foo (args...);

использует перегрузку, тогда как

num_args <T...> ();

использует специализацию.

Перегрузка может справиться с базовым случаемно специализация не может использоваться для шаблонов функций (но может быть и для классов), поэтому auxilliary_class<Args...>::value идиоматичен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...