4

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

#include <iostream> 
#include <tuple> 
#include <utility> 

template <class... Ts, size_t... Is> 
void foo(std::tuple<Ts...> t, 
     std::index_sequence<Is...> = {}) { 
    if (sizeof...(Ts) != sizeof...(Is)) { 
     foo(t, std::make_index_sequence<sizeof...(Ts)>{}); 
     return; 
    } 
    (std::cout << ... << std::get<Is>(t)); 
} 

int main() { 
    foo(std::make_tuple(1, 2, 3)); 
} 

Я предполагаю, что тип второго параметра функции foo будет по умолчанию, выведенной на std::integral_sequence<std::size_t> и как таковой у меня нет, чтобы создать вспомогательную функцию для использования Is... индексов в кортеж , но может позвонить по номеру foo со вторым параметром std::make_index_sequence<sizeof...(Ts)>{}.

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

Выше код, составленный с использованием g++-6 и clang++-3.6 с использованием -std=c++1z, работает так, как ожидается.

+2

Помимо раздражающих формулировок вопроса: Да (и не определенно поведение) –

+0

@ DieterLücking на самом деле я не сделал знаете, как правильно это сформулировать ... Спасибо, хотя –

+3

@ DieterLücking: «раздражающий» немного суровый. Название может быть неэлегантным, но это не оскорбительно или провокационно. –

ответ

1

Да. Вы полагаетесь, от [temp.arg.explicit]:

Пакет параметров шаблона для трейлингов (14.5.3), который иначе выведен, будет выведен на пустую последовательность аргументов шаблона.

Что представляет собой «набор параметров шаблонов для шаблонов», на самом деле никогда не определяется должным образом, но все компиляторы здесь интерпретируют Is....


Это говорит о том, что я не буду полагаться на это не потому, что это неправильно, а вместо этого, потому что это затрудняет понимание кода. Тем более, что в этом случае нет простого способ вытащить все элементы лямбды: std::apply():

template <class... Ts> 
void foo(std::tuple<Ts...> t) { 
    std::apply([](auto&... args) { 
     (std::cout << ... << args); 
    }, t); 
}