GCC 和 clang 抛出"no matching function call"但 msvc (cl) 按预期编译和工作
gcc and clang throw "no matching function call" but msvc (cl) compiles and works as expected
我编写了一个小功能模板,该模板在新容器中连接了不同的容器:
#include <vector>
#include <unordered_set>
#include <string>
#include <iostream>
#include <iterator>
namespace impl
{
template <typename OutIterator, typename Container, typename ...Containers>
void join(OutIterator iterator, const Container& container, const Containers& ...containers)
{
for (const auto& item : container)
*iterator++ = item;
join(iterator, containers...); // gcc and clang cannot resolve this call
}
template <typename OutIterator, typename Container>
void join(OutIterator iterator, const Container& container)
{
for (const auto& item : container)
*iterator++ = item;
}
}
template <typename OutContainer, typename ...Containers>
OutContainer join(const Containers& ...containers)
{
OutContainer container;
auto it = std::inserter(container, container.end());
impl::join(it, containers...);
return container;
}
int main()
{
using namespace std;
vector<string> a = {"one"s, "two"s, "three"s};
unordered_set<string> b = {"four"s, "five"s };
auto res = join<unordered_set<string>>(a, b);
for (auto& i : res)
cout << i << "n";
return 0;
}
使用/std:C 17使用MSVC(CL.EXE(编译和工作正常。但是,使用Clang-6.0或GCC-7.3编译时,会抛出编译器错误。IE。GCC说
no matching function for call to 'join(std::insert_iterator<std::unordered_set<std::__cxx11::basic_string<char> > >&)'
显然未定义具有此签名的功能。但是我不明白为什么它试图调用这样的功能。是否应该像这样解决
// in main()
join<unordered_set<string>>(a, b);
unordered_set<string> join(const vector<string>& a, const unordered_set<string>& b);
void impl::join(std::insert_iterator<unordered_set<string>> iterator, const vector<string>& a, const unordered_set<string>& b);
void impl::join(std::insert_iterator<unordered_set<string>> iterator, const unordered_set<string>& b);
为什么GCC尝试实例化join(std::insert_iterator<std::unordered_set<std::__cxx11::basic_string<char>>>&)
?
这是使用编译器资源管理器的示例。
gcc和clang是正确的。MSVC仍然有适当的模板名称查找(即"两相查找"(的问题。
join
,在 join(iterator, containers...)
中,是一个因名称。查找该名称的候选人是:
- 模板定义点上的所有名称。此查找只是找到自己(variadic的超载(,而不是其他过载(2-arg一个(,因为尚未声明。
- ADL可以在其论点上找到的所有名称。这些参数都没有
impl
作为关联的名称空间,因此也找不到其他过载。
在这种情况下,修复是微不足道的:只需重新订购两个join()
超载即可。这样可以确保通过第一个子弹点找到2-ARG join()
。
请注意,在C 17中,您甚至不需要两个过载。只有一个很好:
template <typename OutIterator, typename Container, typename... Containers>
void join(OutIterator iterator, Container const& container, Container const&... containers) {
for (auto const& item : container) {
*iterator++ = item;
}
if constexpr(sizeof...(Containers) > 0) {
join(iterator, containers...);
}
}
还考虑使用std::copy()
而不是循环。实际上允许:
template <typename OutIterator, typename... Containers>
void join(OutIterator iterator, Container const&... containers) {
using std::begin;
using std::end;
(iterator = std::copy(begin(containers), end(containers), iterator), ...);
}
相关文章:
- 当我编译webrtc服务器时,Windows上只支持clang-cl
- MSYS2 MinGW64 在 Windows 上构建 GMP/MPFR 作为静态库,并将它们链接到使用 CL 编译的
- 如何在 Azure 应用服务中使用 cl.exe 编译 C++ 代码并生成可执行文件
- CMake 和 Visual Studio 2015 - C 编译器 cl.exe 无法编译简单的测试程序
- 如何阻止 cmake 使用 cl 编译?
- GCC 和 clang 抛出"no matching function call"但 msvc (cl) 按预期编译和工作
- G++ 和 CL(VS2017) 都编译成功,但 cl 编译的可执行文件运行异常
- CL.EXE无法编译简单的测试程序VS2017
- 使用不同工具集使用Cl.EXE编译
- cpp文件不使用cl编译,但在Visual Studio中编译得很好
- Windows 8.1上的clang cl编译错误
- 编译一个基本的openCL程序错误:cl.hpp中未解析的includes
- 使用Visual c++ Express 2010 IDE编译和使用cl命令在控制台下编译时,exe大小不同
- 命令行编译使用cl.exe
- 使用 VS5 编译 CUDA 2012 时出现错误"nvcc cannot find a supported cl version"
- 我应该使用哪些编译选项来使用cl.exe与Boost链接
- Visual Studio 2010 - MS C++ (CL) 编译的可执行文件在 Windows 2000 上不起作
- 如何将OpenCL内核文件(.cl)编译为llvm IR文件
- VS2015的多处理器编译在运行cl时会产生"not enough quota is available to process this command".exe
- 从MVS 2013编译带有OMIT选项的cl.exe时,sqlite3错误