using namespace是否影响内联函数?Clang与GCC/MSVC行为差异问询
Clang在范围for循环中错误匹配全局
operator*的标准合规性疑问 我们声明了一个无约束的ns::operator*模板,在块作用域中通过using namespace ns引入命名空间后调用模板函数foo<T>。此时Clang在foo内部的范围for循环读取迭代器时,错误选用了ns::operator*——但这里并未涉及ns内的任何类型,ADL(参数依赖查找)本不该引入该候选函数。
示例代码
namespace ns { template <typename T> constexpr auto operator*(T&& /*value*/) { struct custom_type {}; return custom_type{}; }; } // namespace ns template <typename T> constexpr void foo() { std::vector<T> vec{}; for (const auto& curr : vec) { static_assert(std::is_same_v<const T&, decltype(curr)>); } } int main() { using namespace ns; foo<int>(); }
现象与差异
- Clang下
static_assert失败,报错信息:
error: static assertion failed due to requirement 'std::is_same_v<const int &, const custom_type &>'
汇编代码确认Clang确实选用了ns::operator*。
- 相同代码在GCC和MSVC中可正常通过断言。
复现相关条件
- 手动在
foo内部直接调用operator*时,无法复现该问题; - 当
foo不是模板函数,或者移除constexpr修饰时,Clang中的断言可正常通过; - 推测问题源于Clang内联
foo<T>时,错误地将ns::operator*纳入了重载候选范围。
核心疑问
Clang与GCC/MSVC的行为差异中,哪一方符合C++标准?还是该场景属于未指定/未定义行为?
内容的提问来源于stack exchange,提问作者fdan
相关产品推荐
相关产品推荐

