Могу ли я использовать область класса, например пространство имен, вместо того, чтобы ставить все префиксы с именем класса - PullRequest
2 голосов
/ 11 июля 2020

Итак, внутри файлов заголовков я могу сделать

namespace X {
    doThis();
}

, а в файле реализации я могу

namespace X {
   doThis() { .... }
}

Но если у меня есть класс

class X {
    public:
    doThis();
};

Можно ли сделать что-то подобное в файле реализации

class X {
    doThis() { .... }
}

вместо X::doThis() { .... }?

1 Ответ

0 голосов
/ 11 июля 2020

Там есть «Java hack» ¹, где вы «наследуете» от класса, чтобы получить его члены в свое пространство имен:

class MyUserType : /*protected|private*/ X {

     void foo() {
         doThis(); // works
     }
}

Конечно, это работает только с

  • класс не определяет дополнительных (нестатических c) функций, которые мешают при наследовании
  • ваш вызывающий код находится в классе, который может наследовать от типа
  • производного class не является шаблоном, потому что двухэтапный поиск снова делает вещи странными (хотя вы можете использовать объявления using, чтобы смягчить их, поименно)

Re: stati c элементы данных / определение вне класса

В комментариях у вас, кажется, в основном проблема с краткостью кода. Посмотрите на

Отказ от ответственности: следующие примеры в основном скопированы из cppreference

  1. inline переменных (c ++ 17), который касается переменных stati c уровня пространства имен, которые также применяются к членам класса:

    enter image description here

  • constexpr/const static member initialization right in the declaration.

    If a static data member of integral or enumeration type is declared const (and not volatile), it can be initialized with an initializer in which every expression is a constant expression, right inside the class definition:

     struct X
     {
         const static int n = 1;
         const static int m{2}; // since C++11
         const static int k;
     };
     const int X::k = 3;
    
  1. члены constexpr даже должны иметь инициализатор в объявлении:

    struct X {
        constexpr static int arr[] = { 1, 2, 3 };        // OK
        constexpr static std::complex<double> n = {1,2}; // OK
        constexpr static int k; // Error: constexpr static requires an initializer
    };
    
  2. Обратите внимание, что в некоторых случаях вам могут потребоваться внеклассные определения, но без инициализатора:

    Если константа не является встроенной (поскольку C ++ 17) stati c элемент данных или элемент данных constexpr stati c (начиная с C ++ 11) (до C ++ 17²) is odr-used , определение в области пространства имен по-прежнему требуется, но не может иметь инициализатора. Определение может быть предоставлено, даже если оно избыточно (начиная с C ++ 17).

    struct X {
        static const int n = 1;
        static constexpr int m = 4;
    };
    const int *p = &X::n, *q = &X::m; // X::n and X::m are odr-used
    const int X::n;             // … so a definition is necessary
    constexpr int X::m;         // … (except for X::m in C++17)
    

¹ в течение длительного времени Java не имело перечислений, поэтому вы должны определить stati c константы в базовом классе и "унаследовать" от него, чтобы получить константы.

² Если член данных stati c объявлен constexpr, он неявно встроен и не требует повторного объявления в области пространства имен. Это повторное объявление без инициализатора (ранее требовалось, как показано выше) по-прежнему разрешено, но не рекомендуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...