Извините за смутное название, но я не смог придумать лучшего.
Я написал функцию для выравнивания контейнеров:
template <typename Container, typename OutIt>
void flatten(const Container& container, OutIt res)
{
if constexpr (std::is_convertible_v<typename Container::value_type, typename std::iterator_traits<OutIt>::value_type>)
{
for (const auto& value : container)
{
*res = value;
++res;
}
}
else
{
for (const auto& subContainer : container)
flatten(subContainer, res);
}
}
И я хотел, чтобы оно использовалось как:
vector<vector<int>> test = {{1}, {2, 3, 4}, {5, 6}, {7}};
vector<int> res;
flatten(test, std::back_inserter(res));
Это должно в основном копировать все вложенные значения из test
в res
, так что res == { 1, 2, 3, 4, 5, 6, 7 }
.
Однако, если я хочу скомпилировать код, компилятор выдает некоторые ошибки, которые в основном говорят о том, что код в ветви else
компилируется вместо блока if constexpr
.
т.е. Первый экземпляр - void flatten<vector<vector<int>>, OutIt>()
, который является правильным. Второй экземпляр (который запускается блоком else
) - это void flatten<vector<int>, OutIt>()
, что также правильно. Но для 2-го экземпляра выражение if constexpr
должно иметь значение true
, так как vector<int>::value_type
равно int
и std::iterator_traits<OutIt>::value_type>
также равно int
. Но каким-то образом компилятор пытается создать третий шаблон void flatten<int, OutIt>()
, который вызывает ошибки компилятора (потому что я пытаюсь перебрать целое число).
Почему компилятор создает экземпляр 3-го шаблона?