我有一些定义 niebloid 的代码:
#define FWD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
namespace mylib {
namespace detail {
auto func(struct poison&) = delete;
struct func_function {
constexpr auto operator()(auto&& a) const -> decltype(func(FWD(a))) {
return func(FWD(a));
}
};
}
inline namespace niebloid {
inline constexpr auto func = detail::func_function{};
}
template<typename T>
struct some_type {
template<typename U>
friend constexpr auto func(U&&) -> int {
return 42;
}
};
}
int main() {
return mylib::func(mylib::some_type<int>{});
}
一切看起来都不错,除了 clang 16。
如果我们查看这个一致性视图,我们可以观察到旧版本的 clang 一直到 clang 11 都能很好地处理此代码,而 clang 17 及更高版本也能很好地处理它。
但是 clang 16 并且只有 16 似乎无法编译此代码。
使
some_type
非模板或使隐藏的朋友也非模板似乎不会触发该错误,但这两个选项不适用于我的代码库。
现在提问。是否有一种破坏性最小的解决方法可以使此代码与 clang 16 一起使用,或者此编译器本质上与类似 niebloid 的模式不兼容?
似乎通过使用命名空间,我得到了一种破坏性最小的解决方法,在声明类型、变量和函数的地方几乎没有改变。
与软件工程中的大多数问题一样,多一个间接层可以解决问题:
namespace niebloid {
inline constexpr auto func = detail::func_function{};
}
inline namespace workaround {
using namespace niebloid;
}