Шаблоны в с++
От: vasvladal  
Дата: 19.07.22 13:37
Оценка:
Здравствуйте! На гитхабе увидел такой шаблон.
template<char_t... delimiters>
    struct Delimiter
    {
        static_assert(sizeof...(delimiters) >= 1, "at least one delimiter required");
                static_assert(((delimiters != '"') && ...), "the reserved character \" may not be a delimitor");
                static_assert(((delimiters != '\r') && ...), "newlines may not be a delimitor");
                static_assert(((delimiters != '\n') && ...), "newlines may not be a delimitor");

        constexpr bool operator()(char_t candidate) const noexcept
        {
            return ((candidate == delimiters) || ...);
        }
    };

Кто-нибудь может объяснить смысл ... в нем?
(ISO C++17 Standard (/std:c++17))
Спасибо
Re: Шаблоны в с++
От: DiPaolo Россия  
Дата: 19.07.22 13:44
Оценка:
А что именно вам непонятно? Тут как минимум несколько моментов могут вызвать вопросы.

В-первую очередь, обратите внимание, где и как это используется. Возможно, станет понятнее.
Патриот здравого смысла
Re[2]: Шаблоны в с++
От: DiPaolo Россия  
Дата: 19.07.22 13:47
Оценка:
Здравствуйте, DiPaolo, Вы писали:

DP>А что именно вам непонятно? Тут как минимум несколько моментов могут вызвать вопросы.


DP>В-первую очередь, обратите внимание, где и как это используется. Возможно, станет понятнее.


Ааа. Речь про

...


Это было неочевидно. Я сначала подумал что это элемент повествования (пауза)

Вот же https://en.cppreference.com/w/cpp/language/parameter_pack
Патриот здравого смысла
Отредактировано 19.07.2022 13:47 DiPaolo . Предыдущая версия .
Re[3]: Шаблоны в с++
От: vasvladal  
Дата: 19.07.22 15:06
Оценка:
Здравствуйте, DiPaolo, Вы писали:

DP>Здравствуйте, DiPaolo, Вы писали:


DP>>А что именно вам непонятно? Тут как минимум несколько моментов могут вызвать вопросы.


DP>>В-первую очередь, обратите внимание, где и как это используется. Возможно, станет понятнее.


DP>Ааа. Речь про

DP>

DP>...


DP>Это было неочевидно. Я сначала подумал что это элемент повествования (пауза)


DP>Вот же https://en.cppreference.com/w/cpp/language/parameter_pack


Спасибо за ответ!
Пытаюсь откомпилировать в Qt_5_15_2_MSVC2019_64bit, получаю ошибки:
error: C2059: syntax error: '...'
и
error: C2238: unexpected token(s) preceding ';'
Вот это ... и вызвало вопрос
Re[4]: Шаблоны в с++
От: DiPaolo Россия  
Дата: 19.07.22 15:18
Оценка:
V>Спасибо за ответ!
V>Пытаюсь откомпилировать в Qt_5_15_2_MSVC2019_64bit, получаю ошибки:
V>error: C2059: syntax error: '...'
V>и
V>error: C2238: unexpected token(s) preceding ';'
V>Вот это ... и вызвало вопрос

В первую очередь надо убедиться, что компилируется с включенным флагом C++17 (коллеги в треде подсказали). Вы в этом уверены? Каким образом включаете флаг?
Патриот здравого смысла
Отредактировано 19.07.2022 15:28 DiPaolo . Предыдущая версия .
Re: Шаблоны в с++
От: vopl Россия  
Дата: 19.07.22 15:18
Оценка:
V>Кто-нибудь может объяснить смысл ... в нем?
V>(ISO C++17 Standard (/std:c++17))

https://en.cppreference.com/w/cpp/language/fold
Re: Шаблоны в с++
От: Chorkov Россия  
Дата: 19.07.22 15:25
Оценка:
Здравствуйте, vasvladal, Вы писали:

А какая конкретно версия компилятора используется?
Просто MSVC не сразу освоил fold expression, даже в режиме c++17.

https://godbolt.org/z/cYxYK4G54
Re[2]: Шаблоны в с++
От: vasvladal  
Дата: 19.07.22 15:32
Оценка:
Здравствуйте, Chorkov, Вы писали:

C>Здравствуйте, vasvladal, Вы писали:


C>А какая конкретно версия компилятора используется?

C>Просто MSVC не сразу освоил fold expression, даже в режиме c++17.

C>https://godbolt.org/z/cYxYK4G54


В pro-файле:
CONFIG += c++17
Компилятор:
Qt_5_15_2_MSVC2019_64bit
Re[3]: Шаблоны в с++
От: Chorkov Россия  
Дата: 19.07.22 15:41
Оценка:
Здравствуйте, vasvladal, Вы писали:

V>Здравствуйте, Chorkov, Вы писали:


C>>Здравствуйте, vasvladal, Вы писали:


C>>А какая конкретно версия компилятора используется?

C>>Просто MSVC не сразу освоил fold expression, даже в режиме c++17.

C>>https://godbolt.org/z/cYxYK4G54


V>В pro-файле:

V>CONFIG += c++17
V>Компилятор:
V>Qt_5_15_2_MSVC2019_64bit

Компилятор несколько раз обновлялся. Возможно, что у вас "оригинальная" версия без обновлений (которая неумела fold expression).
Чтобы узнать версию компилятора, зайдите:
Start > Visual Studio 2019 > Visual Studio Tools > VC > x64 Native Tools Command Prompt for VS 2019

Набрать команду cl

Выведет версию в первой строке ответа.
Re: Шаблоны в с++
От: rg45 СССР  
Дата: 19.07.22 20:01
Оценка: 25 (3) +2
Здравствуйте, vasvladal, Вы писали:

V>Здравствуйте! На гитхабе увидел такой шаблон.

V>...
V>Кто-нибудь может объяснить смысл ... в нем?

Это шаблонный класс, предназначенный для хранения символов-разделителей — констант времени компиляции. В этом классе определен функциональный оператор, который используется для проверки, является ли тот или иной символ разделителем. Дополнительно в классе заданы ограничения на количество и состав символов — не меньше одного символа, и разделителем не может быть двойная кавычка и символы конца строки. Для всех проверок используются специальные выражения: fold expressions, которые позволяют без циклов, в рамках одного арифметического или булевого выражения, выполнить перебор всех констант, входящих в состав списка шаблонных параметров переменного размера — parameter packs

Использование может выглятеть примерно так:

http://coliru.stacked-crooked.com/a/61849a4f03987770

#include <iostream>

using char_t = char;

template<char_t... delimiters>
struct Delimiter
{
    static_assert(sizeof...(delimiters) >= 1, "at least one delimiter required");
    static_assert(((delimiters != '"') && ...), "the reserved character \" may not be a delimitor");
    static_assert(((delimiters != '\r') && ...), "newlines may not be a delimitor");
    static_assert(((delimiters != '\n') && ...), "newlines may not be a delimitor");

    constexpr bool operator()(char_t candidate) const noexcept
    {
        return ((candidate == delimiters) || ...);
    }
};

constexpr Delimiter<'.', ',', ';'> is_delimiter;

int main()
{
    std::cout << std::boolalpha;
    std::cout << is_delimiter('a') << std::endl; // false
    std::cout << is_delimiter('7') << std::endl; // false
    std::cout << is_delimiter(',') << std::endl; // true
    std::cout << is_delimiter(';') << std::endl; // true
}


Примечательно, что такие выражения как is_delimiter(',') вычисляются во время компиляции. То есть, эти выражения можно использовать, например, в перечислениях, ключах оператора switch, для параметризации шаблонов и пр.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 20.07.2022 8:26 rg45 . Предыдущая версия . Еще …
Отредактировано 19.07.2022 20:27 rg45 . Предыдущая версия .
Отредактировано 19.07.2022 20:03 rg45 . Предыдущая версия .
Re[2]: Шаблоны в с++
От: vasvladal  
Дата: 21.07.22 10:48
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, vasvladal, Вы писали:


V>>Здравствуйте! На гитхабе увидел такой шаблон.

V>>...
V>>Кто-нибудь может объяснить смысл ... в нем?

R>Это шаблонный класс, предназначенный для хранения символов-разделителей — констант времени компиляции. В этом классе определен функциональный оператор, который используется для проверки, является ли тот или иной символ разделителем. Дополнительно в классе заданы ограничения на количество и состав символов — не меньше одного символа, и разделителем не может быть двойная кавычка и символы конца строки. Для всех проверок используются специальные выражения: fold expressions, которые позволяют без циклов, в рамках одного арифметического или булевого выражения, выполнить перебор всех констант, входящих в состав списка шаблонных параметров переменного размера — parameter packs


R>Использование может выглятеть примерно так:


R>http://coliru.stacked-crooked.com/a/61849a4f03987770


R>
R>#include <iostream>

R>using char_t = char;

R>template<char_t... delimiters>
R>struct Delimiter
R>{
R>    static_assert(sizeof...(delimiters) >= 1, "at least one delimiter required");
R>    static_assert(((delimiters != '"') && ...), "the reserved character \" may not be a delimitor");
R>    static_assert(((delimiters != '\r') && ...), "newlines may not be a delimitor");
R>    static_assert(((delimiters != '\n') && ...), "newlines may not be a delimitor");

R>    constexpr bool operator()(char_t candidate) const noexcept
R>    {
R>        return ((candidate == delimiters) || ...);
R>    }
R>};

R>constexpr Delimiter<'.', ',', ';'> is_delimiter;

R>int main()
R>{
R>    std::cout << std::boolalpha;
R>    std::cout << is_delimiter('a') << std::endl; // false
R>    std::cout << is_delimiter('7') << std::endl; // false
R>    std::cout << is_delimiter(',') << std::endl; // true
R>    std::cout << is_delimiter(';') << std::endl; // true
R>}
R>


R>Примечательно, что такие выражения как is_delimiter(',') вычисляются во время компиляции. То есть, эти выражения можно использовать, например, в перечислениях, ключах оператора switch, для параметризации шаблонов и пр.


Cпасибо большое за развернутый ответ! В VS-2019 все собирается отлично, в Qt c этим же компилятором выдает ошибки, как и писал выше...
Re[3]: Шаблоны в с++
От: K13 http://akvis.com
Дата: 22.07.22 07:12
Оценка:
V>Cпасибо большое за развернутый ответ! В VS-2019 все собирается отлично, в Qt c этим же компилятором выдает ошибки, как и писал выше...

У меня фолд компилится нормально в 2017 с Qt5.9.7
в .pro стоит

win32:QMAKE_CXXFLAGS += -std:c++17
Re[4]: Шаблоны в с++
От: σ  
Дата: 22.07.22 07:26
Оценка:
K13>У меня фолд компилится нормально в 2017 с Qt5.9.7
K13>в .pro стоит

K13>win32:QMAKE_CXXFLAGS += -std:c++17


А `CONFIG += c++17`, чтобы сразу для всех платформ, не прокатывает?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.