Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826

Сравнение строковых литералов

24.08.2016, 12:41. Показов 2330. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день,

есть кроссплатформенные гарантии на то, что адреса одного и тоже же строкового литерала внутри одного .exe/.lib будут равны? Про .lib имеется статическая линковка несколько проектов в один ?

C++
1
2
3
4
5
6
7
8
9
10
11
void add( const char* const s, function<void()> fn )
{
      cont[s] = fn;
}
bool foundSome( const char* const s )
{
      return std::find( std::begin(cont), std::end(cont), s) != std::end( cont );
}
 
add( "Archer" );
foundSome( "Archer" );
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.08.2016, 12:41
Ответы с готовыми решениями:

Префиксы u и U для строковых литералов
Есть код //g++ 5.4.0 #include &lt;iostream&gt; int main() { wchar_t title = L&quot;Chief Astrogator&quot;; // строка w_char ...

Каков тип строковых литералов?
Каков тип rvalue строки &quot;Hello&quot;? const char* const или const char* ? const char* some1 = &quot;Hello&quot;;

Qt Creator, некорректный парсинг строковых литералов
Как победить эти предупреждения в Qt Creator? ClangCodeModel кключен.

15
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
24.08.2016, 13:17
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
есть кроссплатформенные гарантии на то, что адреса одного и тоже же строкового литерала внутри одного .exe/.lib будут равны?
Нет, таких гарантий нет.

Добавлено через 6 минут
rikimaru2013, впрочем, возможно тебя заинтересует вот это.
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
24.08.2016, 13:20  [ТС]
DrOffset, спасибо почитаю. Я по некоторым причинам ушёл от enum и перешёл на строки для абстрактной фабрики и думаю как бы соптимизировать сравнение, ведь в 80% обращений, я передаю литерал
0
Падаван С++
 Аватар для obivan
447 / 261 / 89
Регистрация: 11.11.2014
Сообщений: 916
24.08.2016, 13:32
rikimaru2013, а что если попробовать что то типо такого
C++
1
#define str "str"
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
24.08.2016, 13:48
Цитата Сообщение от obivan Посмотреть сообщение
а что если попробовать что то типо такого
Это ничего не даст, если ему нужен адрес.
2.13
Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation-defined.
Поэтому даже такой код
C++
1
"str" == "str"
может в зависимости от реализации давать либо true, либо false.
2
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
24.08.2016, 14:04
я бы так сделал
C++
1
2
3
4
5
6
7
8
inline const std::string& my_str()
{
    static std::string str { "My String" };
    return str;
}
 
add( my_str() );
foundSome( my_str() );
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
24.08.2016, 14:08  [ТС]
Kastaneda, разве можно хранить константную ссылку в STL контейнерах?
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
24.08.2016, 14:28
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
ведь в 80% обращений, я передаю литерал
Сделать перегрузку, принимающую объект какого-нибудь ConstExprString класса, который бы мог в compile-time проверить соответствие.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
24.08.2016, 14:33
rikimaru2013, а, я на код не глянул. Ну идею, думаю, ты понял)
1
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
24.08.2016, 16:12
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//clang 3.7.0
 
#include <iostream>
#include <type_traits>
 
 
template<typename T>
class StringLiteralsWrapper
{
public:
    constexpr StringLiteralsWrapper(T const * const arr) noexcept
        : literalPtr(arr)
    {
    }
    constexpr StringLiteralsWrapper(const StringLiteralsWrapper&) noexcept = default;
    constexpr bool operator==(const StringLiteralsWrapper<T> &rhv) const noexcept
    {
        std::size_t index = 0;
        for(; literalPtr[index] && rhv.literalPtr[index]; ++index)
        {
            if(literalPtr[index] != rhv.literalPtr[index])
            {
                return false;
            }
        }
        return literalPtr[index] == rhv.literalPtr[index];
    }
private:
    T const * const literalPtr;
};
 
 
 
int main()
{
    constexpr auto Literal1 = StringLiteralsWrapper<char>("xxx");
    constexpr auto Literal2 = StringLiteralsWrapper<char>("xxx");
    constexpr auto Literal3 = StringLiteralsWrapper<char>("xxy");
    char arr1[(Literal1 == Literal3)+1];
    char arr2[(Literal1 == Literal2)+1];
    std::cout << sizeof(arr1) << " " << sizeof(arr2) << std::endl;
}
gcc 4.9 и VS не тянут,
gcc 5 и clang 3.7 - ok - http://rextester.com/QBT85865
Цитата Сообщение от облачной IDE
1 2
Но тогда у Вас должны быть соответствующие функции, которые могут работать как constexpr.

Добавлено через очень много минут
Чуть добавил:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<typename T>
constexpr StringLiteralsWrapper<T> makeLiteral(T const * const ptr)
{
    return StringLiteralsWrapper<T>(ptr);
}
 
 
constexpr StringLiteralsWrapper<char> operator "" _lit(char const * const ptr, std::size_t size)
{
    return StringLiteralsWrapper<char>(ptr);
}
 
 
int main()
{
    char arr1[("xxx"_lit == "xxy"_lit) + 1];
    char arr2[("xxx"_lit == "xxx"_lit) + 1];
    std::cout << sizeof(arr1) << " " << sizeof(arr2) << std::endl;
}
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
24.08.2016, 16:35
rikimaru2013, вот выжимка из моего примера во втором посте.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <utility>
 
namespace ct
{
 
template <char ...Chars>
struct string
{
    enum { length = sizeof...(Chars) - 1 };
 
    static char const value[];
};
 
template <char ...Chars>
char const string<Chars...>::value[] = { Chars... };
 
template <typename Str, typename I>
struct string_gen;
 
template <typename Str, size_t ...I>
struct string_gen<Str, std::index_sequence<I...>>
    : string<Str().chars[I]...>
{ };
 
template <typename Str, size_t Len>
struct make_string
    : string_gen<Str, std::make_index_sequence<Len>>
{ };
 
} // ct
 
#define UNIQUE(str) []() \
    {                                                          \
        struct S_ { char const * chars = (str); };             \
        return ::ct::make_string<S_, sizeof((str))>::value;    \
    }()
 
int main()
{
    std::cout << (UNIQUE("a") == UNIQUE("a")) << std::endl;
}
http://rextester.com/HAOVY76652

Работает на VS 2015, GCC 4.9 (можно и более ранних, если перейти на С++11) и Clang.
1
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
24.08.2016, 16:59
DrOffset, не сможем всё это применить там, где требуется constexpr, хотя это врядли понадобится.
Хотя, если немного переделать, то, наверное, сможем
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
24.08.2016, 17:08
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
не сможем всё это применить там, где требуется constexpr, хотя это врядли понадобится.
Пример можно?
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
24.08.2016, 17:14
Цитата Сообщение от DrOffset Посмотреть сообщение
Пример можно?
C++
1
2
3
4
enum 
{
    x = (UNIQUE("a") == UNIQUE("a");//error
}
C++
1
char arr[(UNIQUE("a") == UNIQUE("a")) + 1];//error
C++
1
constexpr bool x = (UNIQUE("a") == UNIQUE("a"));//error
Всё дело в лямбде, которая не constexpr.
Мой вариант можно в данных контекстах использовать, но он тоже требует доработки.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
24.08.2016, 17:31
HelicopterK52, а, да. Это из-за лямбды. А так само выражение внутри лямбды вполне себе constexpr.

Добавлено через 7 минут
HelicopterK52, в принципе можно и другим путем пойти...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/config/limits.hpp>
 
namespace ct
{
 
template <char ...Chars>
struct string
{
    static constexpr char const value[sizeof...(Chars)] = { Chars... };
};
 
template <char ...Chars>
char const string<Chars...>::value[];
 
} // ct
 
#define STRING_TO_CHARS_BY_ONE(Z, N, STR) \
        BOOST_PP_COMMA_IF(N) N >= sizeof(STR) ? '\0' : STR[N]
 
#define STRING_TO_CHARS(LEN, STR)  \
        BOOST_PP_REPEAT(LEN, STRING_TO_CHARS_BY_ONE, STR)
 
#define UNIQUE(STR) ::ct::string<STRING_TO_CHARS(100, STR)>::value
 
int main()
{
    enum 
    {
        x = (UNIQUE("a") == UNIQUE("a")) //ok
    };
}
http://rextester.com/EPME79197
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
24.08.2016, 18:03
Цитата Сообщение от DrOffset Посмотреть сообщение
в принципе можно и другим путем пойти...
и другим - дождаться c++17 и сделать так:
C++
1
2
#define UNIQUE(str) []() constexpr \
...


Добавлено через 6 минут
Посмотрел, GCC 7 надо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.08.2016, 18:03
Помогаю со студенческими работами здесь

Visual Studio: регулярное выражение для поиска строковых литералов с русскими буквами
Доброго времени суток всем! В проектах на VS C++ нужно искать строковые литералы содержащие хотя бы одну русскую букву. Например...

С: Удаление строковых литералов из памяти
Добрый день. Вопрос именно по Си (без ++) и именно для моей конкретной ситуации. Поэтому malloc/free не предлагать Собственно вопрос...

Сравнение строковых массивов
Здравствуйте! Задача такая Написать функцию, печатающую строку-вопрос (ее аргумент), принимающую с клавиатуры только ответ “YES” или...

Сравнение строковых переменных
сделал код section .data boss db &quot;Hello boss&quot;,0 guest db &quot;Hello guest&quot; SECTION .text global greet greet: cmp edi, esi ...

Сравнение строковых массивов
Здравствуйте. У меня есть 2 массива и 2 текстовых файла (в одном лежат вопросы, в другом - ответы). При запуске программы выходит 1-й...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru