Здравствуйте, Alexey F, Вы писали:
AF>Приведённый ниже класс, случайно, не избавлен от этих недостатков (спрашиваю, потому что не уверен, как с порядком инициализации при инициализации POD-структур так, как показано ниже)?
Если эта переменная some объявлена в пространстве имён (возможно, глобальном), то её инициализация будет выполняться статически:
5.19/4:
An address constant expression is a pointer to an lvalue designating an object of static storage duration, a string literal (2.13.4), or a function.
8.5.1/14:
When an aggregate with static storage duration is initialized with a brace-enclosed initializer-list, if all the member initializer expressions are constant expressions, and the aggregate is a POD type, the initialization shall be done during the static phase of initialization (3.6.2); otherwise, it is unspecified whether the initialization of members with constant expressions takes place during the static phase or during the dynamic phase of initialization.
Но у std::basic_string есть ещё полезные операции типа поиска и всяческих сравнений. IMHO, создавать громадный костыль, имитирующий std::basic_string, ради устранения мелочных проблем с динамической инициализацией смысла нет.
В принципе, при работе с локальными статическими переменными выгоду извлечь можно. Статическая инициализация не создаёт проблем в условиях многопоточности.
В
соседнем топикеАвтор: steep8
Дата: 15.08.09
обсуждали объявление строковых констант как char const* const против std::string const. В качестве аргумента к char const* const приводилось сложность инициализации std::string const перед использованием (из-за неопределённого порядка инициализации). А против char const* const выдвигались аргументы о неудобстве, например, конкатенации строк.
Приведённый ниже класс, случайно, не избавлен от этих недостатков (спрашиваю, потому что не уверен, как с порядком инициализации при инициализации POD-структур так, как показано ниже)?
namespace Tools {
template< class CharType, class Traits = std::char_traits<CharType>, class Allocator = std::allocator<CharType> >
struct basic_string_const {
// Для того, чтобы basic_string_const остался POD, конструкторы и т.п. не определяем.
// Открытый член, чтобы можно было инициализировать как агрегат.
CharType const* body;
// Неявное приведение:
operator CharType const* () const {
return body;
}
// Явные приведения:
CharType const* c_str () const {
return body;
}
// А можно и substr, find и прочие - по вкусу...
std::basic_string<CharType, Traits, Allocator> str () const {
return std::basic_string<CharType, Traits, Allocator> ( body );
}
};
template<class CharType, class Traits, class Allocator, class T>
std::basic_string<CharType, Traits, Allocator> operator+ (
basic_string_const<CharType, Traits, Allocator> const& first,
T const& second
) {
return first.str () + second;
}
template<class CharType, class Traits, class Allocator, class T>
std::basic_string<CharType, Traits, Allocator> operator+ (
T const& first,
basic_string_const<CharType, Traits, Allocator> const& second
) {
return first + second.str ();
}
typedef basic_string_const<char> string_const;
typedef basic_string_const<wchar_t> wstring_const;
}
И пример использования:
Tools::string_const some = { "C:\\MyDoc" };
// ...
std::string result = some + '\\' + "SomeFile.png";
Здравствуйте, Николай Ивченков, Вы писали:
НИ>Но у std::basic_string есть ещё полезные операции типа поиска и всяческих сравнений. IMHO, создавать громадный костыль, имитирующий std::basic_string, ради устранения мелочных проблем с динамической инициализацией смысла нет.
Подумав, пришёл к выводу что раздувать basic_string_const методами find, substr и т. п. нет смысла, так что костыль получается не громадный