Comments 47
Почему вы не стали использовать пользовательские литералы вместо страшного make_static_string?
А почему написали свой велосипед, а не использовали, например, boost::hana?
Нет, но можно например использовать такой workaround с помощью хэшей:
template<unsigned long long> constexpr auto greet() {return "Hello, guest!";}
template<> constexpr auto greet<static_string_hash("alice")>() {return "Hello, Alice!";}
template<> constexpr auto greet<static_string_hash("bob")>() {return "Hello, Bob!";}
constexpr auto name = make_static_string("alice");
constexpr auto greeting = greet<name.hash()>();
std::cout << greeting << std::endl;
Прошу прощения, прочитал "определять" как "передавать"
В C++ известная проблема со строковыми литералами в шаблонных параметрах, поэтому если так хочется именно в шаблонных параметрах, то придется определять строку как список символов, например так:
template<char ... Chars> struct static_string{};
template<char ... Chars1, char ... Chars2>
constexpr auto static_string_concat(
const static_string<Chars1 ... >& str1,
const static_string<Chars2 ... >& str2) {
return static_string<Chars1 ..., Chars2 ...>{};
}
template<char ch, char ... Chars>
std::ostream& operator<<(std::ostream& os, const static_string<ch, Chars ...>& str) {
os << ch << static_string<Chars ... >{};
return os;
}
std::ostream& operator<<(std::ostream& os, const static_string<>& str) {
return os;
}
constexpr static_string<'a', 'b', 'c'> str1;
constexpr static_string<'d', 'e', 'f'> str2;
constexpr auto str = static_string_concat(str1, str2);
std::cout << str << std::endl;
Честно говоря, этот вариант я тоже рассматривал, но в итоге ничего толкового из него не вышло
Все-таки возможно сделать этот вариант хорошо с помощью оператора пользовательского литерала:
template<typename Char, Char ... Chars>
constexpr static_string<Char, Chars ... > operator"" _ss() {
return static_string<Char, Chars ... >{};
};
constexpr auto str1 = "abc"_ss;
constexpr auto str2 = "def"_ss;
constexpr auto str = str1 + str2 + str1;
std::cout << str << std::endl;
Пожалуй, вынесу это в статью
Тип символов вынести в шаблонный параметр для поддержки wchat_t
constexpr size_t length() const {
return Size - 1;
}
constexpr size_t size() const {
return Size;
}
, возвращающие разные значения, что может приводить к множеству ошибок.Давайте ссылку на вашу проверку кода в языке.
Поскольку constexpr for еще не изобрели
Э… https://wandbox.org/permlink/o1dC3wWbXzEPy7Z1
Вы точно про C++14 говорите?
Это почему это? Можно заставить компилятор инициализировать глобальные переменные в определенном порядке.
Для GCC это init_priority
Для VC++ #pragma init_seg
auto str = «hello» + «world»;
если можно сразу написать
auto str = «helloworld»;
т.е. просто в какой момент получается что всё статично, но при этом не совсем? как?
В статье есть пример с плагинами, есть директория с плагинами path = "/path/to/plugins/" и два плагина plugin1 = "plugin1.so", plugin2 = "plugin2". Чтобы не писать два раза путь так plugin1_path = "/path/to/plugins/plugin1" и plugin2_path = "/path/to/plugins/plugin2" мы используем конкатенацию plugin1_path = path + "plugin1" и plugin2_path = path + "plugin2"
Да, все полностью статично, то есть конкатенация происходит на этапе компиляции
#define plugin1_path path «plugin1»
#define plugin2_path path «plugin2»
Не?
Как вариант, правда я не уверен, что все операции со строками, которые описаны в статье, возможно реализовать на макросах
Путь до плагина сколько раз в программе используется? Один раз при запуске? Это экономия на спичках, мне кажется, и приведет она не только к захламлению кода но и к чему то типа «стоимость товара: один рубля»…
P.S. Была книга 10 лет назад по шаблонам где человек считает таким методом чуть ли не интегралы, а результат программы лишь вывод окончательного результата. Но тема так и не пошла )) И кстати, Intellisense какбы не повесился.
Если у Вас в проекте это не дает большого выигрыша, то конечно, не следует это использовать. Я уверен, в большинстве случаев constexpr char[] будет достаточно.
P.S. А в Nvidia, например, используют compile-time хэш таблицу
https://www.youtube.com/watch?v=kUbWYdlS9v0&list=PLZN9ZGiWZoZoFa2q0NqD6metQxavT2JYP&index=19
const char* helloWorld = "Hello "
"world"
Не?.. Конкатенация на этапе компияции.
Обновил статью с учетом замечаний
Ну, тогда докину еще одно ;)
КМК путь к директории может быть записан и без разделителя в конце. Если кто-то не сильно внимательный исправит PLUGIN_PATH вот так:
const std::string PLUGIN_PATH = "/usr/local/lib/project/plugins";
, будет неочевидно и неприятно. Кроме того, в некоторых ОС используется другой разделитель — это тоже неплохо предусмотреть.
Добавил альтернативный вариант реализации статических строк
Работа со строками на этапе компиляции в современном C++