Использование статических константных структур для группировки связанных констант классов (C ++ 11) - PullRequest
0 голосов
/ 04 июля 2018

Каковы (не) преимущества использования следующего (A):

// .h
class SomeClass
{
    static const struct ConstantGroup
    {
        int a = 1;
        string b = "b";
        // ... etc.
    } CONSTANT;
};
// .cpp
const SomeClass::ConstantGroup SomeClass::CONSTANT;

по сравнению с (B):

// .h
class SomeClass
{
    static const int A;
    static const string B;
    // .. etc.
};
// .cpp
const int SomeClass::A = 1;
const string SomeClass::B = "b";

... для некоторых групп связанных статических констант класса? Предположим, что шаблоны не используются, и что константы содержат простые типы (POD или строки).

Пока я вижу следующие преимущества в пользу (A):

  • Связанные константы могут передаваться как группа РЕДАКТИРОВАТЬ: Как было отмечено в комментариях, это обычно не желательно.
  • Учитывая, что к константам часто обращаются вместе, мы можем создать сокращения для структуры, чтобы улучшить читаемость при необходимости, т.е.: static const auto & SHORTHAND = SomeClass::LONG_NAME_FOR_CONSTANTS;

Какие недостатки, ошибки или другие вещи следует учитывать при использовании этого шаблона?

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Интересно (следует из разговора в комментариях выше с @Henri Menke о string s и string_view s).

Учитывая это:

#include <string>
#include <string_view>
#include <iostream>

static const std::string a = "a";
static const std::string_view b = "b";

int main ()
{
    std::cout << a << "\n";
    std::cout << b << "\n";
}

На Годболт вы можете ясно видеть, что для создания a требуется инициализатор времени выполнения, тогда как b - это константа времени компиляции.

Если вам не нравится читать код, сгенерированный компилятором, попробуйте изменить оба const s на constexpr s. Затем std::string_view все еще компилируется, а std::string нет.

Таким образом, для статических и / или глобальных константных строк constexpr std::string_view = "blah blah blah"; выглядит здесь как хорошее решение, как говорит Анри, потому что он предлагает дополнительную функциональность по сравнению со старым добрым C- строка, ЕСЛИ вы можете использовать C ++ 17 И вы не возражаете против стоимости преобразования их в std::string с (что потребует ее создания) в контекстах, где это что нужно в этот момент в коде.

Если нет, вы вынуждены вернуться к std::string или, возможно, к простым старым C-струнам.


Edit:

Я заметил странный недостаток в std::stringview, глядя на это: он не предлагает operator std::string () метод. Я понятия не имею, почему нет, но это означает, например, что следующее не скомпилируется:

void foo (std::string s)
{
    ...
}

std::string_view sv = ...;
foo (sv);

Это не достаточно хорошо, говорю я, поэтому в духе обмена мнениями (если кто-то еще читает в этот момент), я смиренно предлагаю вам следующее:

#include <string>
#include <string_view>

template <class T> struct MyBasicStringView : public std::basic_string_view <T>
{
    constexpr MyBasicStringView (const T *s) : std::basic_string_view <T> (s) { }
    operator std::basic_string <T> () const { return std::basic_string <T> (this->data ()); }
};

using MyStringView = MyBasicStringView <char>;

Тестовая программа:

static constexpr MyStringView a_static_string_view = "static_string";

std::string foo (std::string s)
{
    return s + " x";
}

#include <iostream>

int main ()
{
    std::cout << a_static_string_view << "\n";
    MyStringView sv = "abcde";
    std::cout << sv << "\n";
    std::cout << foo (sv) << "\n";
}

Выход:

static_string
abcde
abcde x

Живая демоверсия .

0 голосов
/ 04 июля 2018

(A) может быть сложнее оптимизировать, удалив ненужные переменные из конечного исполняемого файла.

Если вы хотите сгруппировать константы, рассмотрите возможность использования namespace для этой цели.

namespace ConstantGroup
{
    constexpr int a = 1;

    // Here best solution might depend on usage and c++ version
    const std::string b;    
}

Передача констант в группе на самом деле не имеет особого смысла. Если что-то действительно постоянное, вам нужно одно определение и всегда использовать его.

Также, если константа очень специфична для одного класса, то сделайте ее (статическим) членом этого класса.

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