无法编译包含"if constexpr"的函数模板实例化
cannot compile function template instantiation containing "if constexpr"
很抱歉标题含糊不清,但我想不出更好的标题。
我写了一个函数来展平容器:
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>()
这也是正确的。但是对于第二个实例,if constexpr
表达式的计算结果应该为true
,因为vector<int>::value_type
是int
的,std::iterator_traits<OutIt>::value_type>
也是int
的。但不知何故,编译器尝试实例化第三个模板void flatten<int, OutIt>()
这会导致编译器错误(因为我尝试迭代整数)。
为什么编译器要实例化第三个模板?
你传入一个std::back_insert_iterator
,value_type
void
。因此,if 语句的真正分支永远不会实例化。
一个可能的解决方案是尝试检查分支的功能。这可以通过std::is_assignable
和一些涉及decltype(*declval<OutIt>())
的样板来完成。
相关文章:
- 模板化类构造函数的模板实例化
- 函数模板实例化、替换和重载解析的顺序是什么?
- 请参阅在 Visual Studio 2019 中捕获 std::exception 时对函数模板实例化消息的引用
- 函数模板实例化的 sfinae
- 如何简洁地编写大量显式函数模板实例化?
- 无法编译包含"if constexpr"的函数模板实例化
- 合格的朋友函数模板实例化
- 函数模板实例化失败
- 使用不完整类型的函数模板实例化
- C++ 具有隐式参数的函数模板实例化
- 声明不带模板的函数模板实例化
- 类和函数模板实例化的Visual Studio dll导出问题
- 关于函数模板实例化的c++规则
- 在多个翻译单元中函数模板实例化的标识
- 创建一系列显式函数模板实例化
- vc++函数模板实例化错误C2664当使用不同的枚举实参时
- 跨编译单元的相同函数模板实例化的地址
- 如何计算函数模板实例化
- 可以实例化 C++ 类模板,但具有相同模板参数的函数模板实例化失败
- 延迟函数模板实例化