标签: injected-class-name

为什么拥有私有基类的声明会使类型名称无法访问?

令我感到惊讶的是,在下面的示例中,声明Middle的基类private使该名称在后续派生中不可用作为类型.

class Base {
public:
  Base(Base const& b) : i(b.i) {}

  int i;
};

class Middle : private Base {            //<<<<<<<<<<<
public:
  Middle(Base const* p) : Base(*p) {}
};

class Upper : public Middle {
public:
  Upper(Base const* p) : Middle(p) {}    //<<<<<<<<<<<
};
Run Code Online (Sandbox Code Playgroud)

用g ++编译(Debian 6.3.0-18 + deb9u1)6.3.0 20170516 ......

g++ -std=c++11 privateBase.cpp
Run Code Online (Sandbox Code Playgroud)

我得到以下诊断:

privateBase.cpp:15:9: error: ‘class Base Base::Base’ is inaccessible within this context
   Upper(Base const* p) : Middle(p) {}
         ^~~~
privateBase.cpp:1:12: note: declared here
 class Base {
            ^ …
Run Code Online (Sandbox Code Playgroud)

c++ injected-class-name

10
推荐指数
1
解决办法
202
查看次数

为什么inject-class-name有时不被视为类模板中的模板名称?

资源

在以下情况中,inject-class-name被视为类模板本身的模板名称:

  • 接下来是<
  • 它用作与模板模板参数对应的模板参数
  • 它是友元类模板声明的详细类说明符中的最终标识符.

所以我试图检查所有3个案例(另外在基础模糊的背景下,虽然我认为这不应该在这里).

第一种情况似乎很简单.

问题是 - 为什么没有注释出实例?他们不在GCC和Clang上,所以我不认为这是一个实施问题

template <template <class> class> struct A;

template <class T> struct Base {};

template <class T> struct Derived: Base<int>, Base<char>
{
    // #1
    typename Derived::Base<double> d;

    // #2

    // using a = A<Base>;

    using a = A<Derived::template Base>;

    // #3

    template<class U1>
    friend struct Base;

    // template<class U>
    // friend struct Derived::template Base;
};
Run Code Online (Sandbox Code Playgroud)

以上规则仅适用于模板本身,而不适用于基础吗?如果是这样,基数的规则是什么,特别是对于最后两个案例?

c++ templates c++14 injected-class-name c++17

6
推荐指数
1
解决办法
138
查看次数

注入的类名可以用作友元声明中的类型名吗?

考虑这个代码:

template <typename T>
class Singleton
{
};

class Logger : public Singleton<Logger> {
    friend class Singleton;
};
Run Code Online (Sandbox Code Playgroud)

它在 gcc 和 clang 中编译,但它有效吗?[temp.local].1 说:

当它与模板参数列表一起使用时,作为模板模板参数的模板参数,或作为朋友类模板声明的详细类型说明符中的最终标识符,它是一个模板名称指的是类模板本身。

粗体部分似乎适用,并且朋友声明似乎需要类型名称而不是模板名称(参见 [class.friend])。

编译器错了还是我误读了标准?

c++ friend-class language-lawyer class-template injected-class-name

5
推荐指数
1
解决办法
132
查看次数

如果函数是在类主体内定义的,我是否需要在成员函数的返回类型中指定typename?

考虑下面的示例:

template <typename T>
class SomeClass {
    // rest of the definition ...

    SomeClass<T>& function1() {
        // ...
        return *this;
    }

    SomeClass& function2() {
        // ...
        return *this;
    }

}
Run Code Online (Sandbox Code Playgroud)

上面两个函数的返回值之间有区别吗?如果不是,应该选择哪一个?

c++ templates generic-programming injected-class-name

4
推荐指数
1
解决办法
74
查看次数

当 Injected-Class-Name 发生时会发生什么?(C++)

根据https://en.cppreference.com/w/cpp/language/injected-class-name

在类作用域中,当前类的名称被视为公共成员名称;这称为注入类名。名称的声明点紧跟在类定义的左大括号之后。

int X;
struct X {
    void f() {
        X* p; // OK. X refers to the injected-class-name
        ::X* q; // Error: name lookup finds a variable name, which hides the struct name
    }
};
Run Code Online (Sandbox Code Playgroud)

那么代码中到底发生了什么?是X* p变成了X::X* p

c++ scope class name-lookup injected-class-name

4
推荐指数
1
解决办法
96
查看次数

在C++中交换class&struct关键字

我读的怪C++的功能,称为大约一个注入的类名 在这里.

我试过按照简单的程序

#include <iostream>
class test
{
    int s{3};
    public:
    int get_s()
    { return s; }
};
int main() {
    class test::test s;  // struct test::test s; also allowed. Why???
    std::cout<<s.get_s();
}
Run Code Online (Sandbox Code Playgroud)

如果我在main()程序的第一行用struct替换class关键字仍然编译并运行正常.在这里查看现场演示.为什么?我不应该得到编译错误吗?为什么编译好?

c++ injected-class-name

1
推荐指数
1
解决办法
181
查看次数

Node * next 和 Node&lt;T&gt; * next 有什么区别?

我正在编写链表的实现

在下面的代码中,Node<T> * next;Node * next; 认为两者的作用与指向 Node 类的对象相同,或者它们之间存在差异。

template<typename T>
class Node{
    T data;
    Node<T>* next;
    Node * next;
    Node()
    {
        next = nullptr;
    }
    Node(T val)
    {
        this->data = val;
        next = nullptr;
    }
};
Run Code Online (Sandbox Code Playgroud)

c++ injected-class-name

1
推荐指数
1
解决办法
216
查看次数