我想为我的类型提供一个隐藏的朋友,同时在内联命名空间中有另一个名称相同的对象。所有的正常类型都很正常。
但是,如果我有一个模板,那么当我实例化模板时,编译器就会出错。
redefinition of 'cpo' as different kind of symbol以下是代码:
namespace lib{
struct CPO{
template<typename... T>
constexpr decltype(auto) operator()(T&&... args) const{
cpo(static_cast<T&&>(args)...);
}
};
inline namespace cpo_impl_{
inline constexpr CPO cpo{};
}
struct Foo1{
friend auto cpo(Foo1){
return 5;
}
};
template <typename T>
struct Foo2{
friend auto cpo(Foo2){
return 6;
}
};
}
int main(){
lib::Foo1 f1{};
lib::cpo(f1); // works fine;
lib::Foo2<int> f2{}; // error here
}下面是一个较小的例子
namespace lib{
inline namespace impl_{
inline constexpr int foo = 5;
}
template <typename T>
struct Bar{
friend auto foo(Bar){
return 4;
}
};
}
int main(){
lib::bar<int> b{};
}顺便说一句,我知道其他技术,如tag_invoke,但在这里,我无法控制名称和库。
发布于 2020-08-19 10:20:40
你的代码格式很好。我是Clang 37556。
用-std=c++2a编译这个格式良好的程序: 名称空间X{内联命名空间Y{ int交换;}模板结构S{友空交换(S&,S&) { };} int main() {X:s s1,s2;交换(s1,s2);} 产生诊断(https://godbolt.org/g/ceWLxY):
但是,没有修复的时间线。
作为解决办法,您可以将Foo2包装在它自己的inline namespace中。
inline namespace disambig_detail {
template <typename T>
struct Foo2{
friend auto cpo(Foo2){
return 6;
}
};
}这应该足以改变声明区域,以避免错误诊断。同时,名称查找应该进行得与名称空间不存在的情况大致相同。
https://stackoverflow.com/questions/63484570
复制相似问题