首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类模板名称中的隐藏朋友与内联命名空间中的另一个符号冲突。

类模板名称中的隐藏朋友与内联命名空间中的另一个符号冲突。
EN

Stack Overflow用户
提问于 2020-08-19 10:01:47
回答 1查看 87关注 0票数 3

我想为我的类型提供一个隐藏的朋友,同时在内联命名空间中有另一个名称相同的对象。所有的正常类型都很正常。

但是,如果我有一个模板,那么当我实例化模板时,编译器就会出错。

代码语言:javascript
复制
redefinition of 'cpo' as different kind of symbol

以下是代码:

代码语言:javascript
复制
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
}

下面是一个较小的例子

代码语言:javascript
复制
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,但在这里,我无法控制名称和库。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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中。

代码语言:javascript
复制
inline namespace disambig_detail {
  template <typename T>
  struct Foo2{
    friend auto cpo(Foo2){
        return 6;
    }
  };
}

这应该足以改变声明区域,以避免错误诊断。同时,名称查找应该进行得与名称空间不存在的情况大致相同。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63484570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档