c++ - 没有前向声明的嵌套函数模板实例在 GCC 上编译,但不在 clang 上编译

标签 c++ language-lawyer

以下内容不能在 clang 中编译,但可以在 GCC ( godbolt ) 中编译:

template <typename K, typename V>
std::ostream& operator<< (std::ostream& o, const std::map<K, V>& map)
{
    const char* sep = "{";
    for (const auto& x : map)
    {
        o << sep << "{" << x.first << ", " << x.second << "}";
        sep = ", ";
    }
    return o << "}";
}

template <typename T>
std::ostream& operator<< (std::ostream& o, const std::vector<T>& vec)
{
    const char* sep = "{";
    for (const auto& x : vec)
    {
        o << sep << x;
        sep = ", ";
    }
    return o << "}";
}

// Usage

int main()
{
    std::map<int, std::vector<int>> t = {{1, {2, 3}}, {4, {5}}};
    std::cout << t << std::endl;
    return 0;
}
谁是对的?
顺便说一句,我知道它是 UB,但是将两个模板定义放在 namespace std 中也使代码在 clang 上编译。
代码借自 Is it possible to define operator<< for templated types?

最佳答案

叮当是对的。你应该搬家 operator<< std::vector的声明之前 operator<< std::map 的定义.
unqualified name lookup ,
(强调我的)

For a dependent name used in a template definition, the lookup is postponed until the template arguments are known, at which time ADL examines function declarations with external linkage (until C++11) that are visible from the template definition context as well as in the template instantiation context, while non-ADL lookup only examines function declarations with external linkage (until C++11) that are visible from the template definition context (in other words, adding a new function declaration after template definition does not make it visible except via ADL).

关于c++ - 没有前向声明的嵌套函数模板实例在 GCC 上编译,但不在 clang 上编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67369741/

相关文章:

c++ - arm-linux-androideabi STL编译报错

c# - 调试混合模式应用程序(c# 和非托管 c++)时出现 "The breakpoint will not currently be hit"错误

C++ 将 'main' 声明为对函数的引用?

c++ - Lambda 转换函数指针比较

c++ - 移动成员函数生成

c++ - 获取 QTextEdit 中每行的大小

c++ - 我们可以使用用户定义的类作为 STL 映射中的键吗?

c++ - 查找节点树的最大路径总和

c - 使用 gets 防止缓冲区溢出

c++ - sizeof(void()) 是合法的表达式吗?