代码之家  ›  专栏  ›  技术社区  ›  LiraNuna

私有模板类/结构可见性

  •  3
  • LiraNuna  · 技术社区  · 14 年前

    print_private_template 当编译器抱怨 print_private_class

    #include <cstdio>
    
    class A
    {
        private:
            template <unsigned T>
            struct B
            {
    
            };
    
            struct C
            {
    
            };
    
        public:
            template <unsigned T>
            B<T> getAb()
            { 
                return B<T>();
            }
    
            C getAc()
            { 
                return C();
            }
    };
    
    template<unsigned T>
    void print_private_template(const A::B<T> &ab)
    {
        printf("%d\n", T);
    }
    
    void print_private_class(const A::C &ac)
    {
        printf("something\n");
    }
    
    int main(int, char**)
    {
        A a;
    
        print_private_template(a.getAb<42>());
    
        print_private_class(a.getAc());
    
        return 0;
    }
    

    这是预期的行为吗?编译器错误/扩展?

    我的目标是让编译器在 二者都 使用 打印私有类 .

    2 回复  |  直到 4 年前
        1
  •  2
  •   dirkgently    14 年前

    Comeau print_private_class

    ComeauTest.c(31):错误:类模板“A::B”(在第7行声明)不可访问 ^ 在基于的“print\u private\u template”实例化过程中检测到 第45行的模板参数<42U>

    -std=c++ -Wall -pedantic

    你的班级 A::C 和类模板 A::B<T> 两者的可见性与任何其他普通成员相同。因此,两者 打印私有类 print_private_template 需要诊断。

    11.8嵌套类

    1 嵌套类是成员,因此具有与任何其他成员相同的访问权限。成员 必须服从。

        2
  •  1
  •   Anonymous    7 年前

    解决此问题的一种方法是将它们封装在非模板结构中:

    template<int I> class MyTemplate
    {
        struct PT
        {
            template<int, typename = void> struct InnerTemplate;
            // ... specialisations here ...
        };
    public:
        typedef typename PT::template InnerTemplate<I>::SomeType SomeType;
    };
    typedef MyTemplate<1>::PT::InnerTemplate<1> ThisWontWork;
    

    error: 'struct MyTemplate<1>::PT' is private within this context
    

    我承认这很难看,尤其是不得不用 PT::template

        3
  •  1
  •   Ciro Santilli OurBigBook.com    4 年前

    它已经为GCC 11修好了

    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41437#c13 (dupe池中的另一个点之前已被 dirkgently

    最小的复制:

    主.cpp

    class Out {
      protected:
        class In {};
    };
    
    template <class C>
    void f() { Out::In in; }
    
    int main() {
        f<Out>();
    }
    

    g++-10 -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
    

    但在 clang++ 10:

    void f() { Out::In in; }
                    ^
    main.cpp:3:11: note: declared protected here
        class In {};
              ^
    1 error generated
    

    以上在GCC中失败是因为 f 是一个模板函数。