Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 30.09.15 16:21
Оценка:
Заглянул в С++14, нашёл шаблонные переменные.

Тут же решил воплотить давнее желание — собрать указатели на все локальные строки в глобальный map, но уже на первом шаге получил ошибку: "error: use of deleted function".

Зато понял, что имена переменных могут включать в себя угловые скобки (бессмысленная возможность):
#include <iostream>
     
template<class T>
int len = 2;
     
template<class Fn>
const char* s_str = Fn();
     
//template<class Fn>
//auto x = Fn();
     
int main()
{
    class centimeter {};
    class meter {};
    class nothing {};
     
    len<centimeter> = 100 * len<meter>;
     
    std::cout << len<nothing> << ',' << len<centimeter> << std::endl;
     
    const char* str = "asdf";
     
    auto oGetStr = [str]()->const char* {return str;};
    //const char* p = s_str<decltype(oGetStr)>; // error
     
    auto o2and2 = []()->int{return 2 + 2;};
    //int n = x<decltype(o2and2)>; // error
     
    return 0;
}



Может уже появился какой способ собрать указатели на локальные строки в глобальных переменных ? (Например, шаблон параметризованный локальной строкой...)
И каждый день — без права на ошибку...
Re: Чудны способности твои, о стандарт !
От: Evgeny.Panasyuk Россия  
Дата: 30.09.15 16:27
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Может уже появился какой способ собрать указатели на локальные строки в глобальных переменных ? (Например, шаблон параметризованный локальной строкой...)


Поясни что нужно конкретно. Например передавать compile-time строки в шаблоны можно с некоторыми ухищрениями. А вот что ты понимаешь под "собрать"?
Re: Чудны способности твои, о стандарт !
От: VTT http://vtt.to
Дата: 30.09.15 16:37
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Заглянул в С++14, нашёл шаблонные переменные.


BFE>Тут же решил воплотить давнее желание — собрать указатели на все локальные строки в глобальный map


Что? Зачем?

BFE> но уже на первом шаге получил ошибку: "error: use of deleted function".


BFE>template<class Fn>

BFE>const char* s_str = Fn();

BFE> auto oGetStr = [str]()->const char* {return str;};

BFE> //const char* p = s_str<decltype(oGetStr)>; // error

decltype(oGetStr) выозвратит тип ламбды
в выражении справа будет вызваться конструктор? экземпляра этой ламбды
const char* s_str = Fn();

BFE>Может уже появился какой способ собрать указатели на локальные строки в глобальных переменных ? (Например, шаблон параметризованный локальной строкой...)


BFE>Зато понял, что имена переменных могут включать в себя угловые скобки (бессмысленная возможность):


Как это?
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[2]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 30.09.15 16:45
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

BFE>>Может уже появился какой способ собрать указатели на локальные строки в глобальных переменных ? (Например, шаблон параметризованный локальной строкой...)

EP>Поясни что нужно конкретно. Например передавать compile-time строки в шаблоны можно с некоторыми ухищрениями. А вот что ты понимаешь под "собрать"?

Допусти, что все строки в программе обрамлены макросом:

void fun()
{
    std::cout << TT("asdf") << std::endl;
}


Можно ли сделать так, чтобы была создана глобальная переменная содержащая список всех таких строк. Это может быть полезно при переводе сообщений на другой язык.
И каждый день — без права на ошибку...
Re[2]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 30.09.15 16:48
Оценка:
Здравствуйте, VTT, Вы писали:

BFE>>Зато понял, что имена переменных могут включать в себя угловые скобки (бессмысленная возможность):

VTT>Как это?
В примере же есть:
len<centimeter> = 100 * len<meter>;

len<centimeter>
и
len<meter>
— это две разные переменные типа int.
И каждый день — без права на ошибку...
Re[3]: Чудны способности твои, о стандарт !
От: watchmaker  
Дата: 30.09.15 16:49
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Допусти, что все строки в программе обрамлены макросом:

BFE>Можно ли сделать так, чтобы была создана глобальная переменная содержащая список всех таких строк. Это может быть полезно при переводе сообщений на другой язык.

Но ведь уже 20 лет gettext работает именно таким образом.
Re[4]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 30.09.15 16:58
Оценка:
Здравствуйте, watchmaker, Вы писали:

BFE>>Допусти, что все строки в программе обрамлены макросом:

BFE>>Можно ли сделать так, чтобы была создана глобальная переменная содержащая список всех таких строк. Это может быть полезно при переводе сообщений на другой язык.

W>Но ведь уже 20 лет gettext работает именно таким образом.


Неужели? Я думал, что для использования gettext'а нужны сторонние утилиты.
И каждый день — без права на ошибку...
Re[3]: Чудны способности твои, о стандарт !
От: VTT http://vtt.to
Дата: 30.09.15 17:00
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>В примере же есть:

BFE>
BFE>len<centimeter> = 100 * len<meter>;
BFE>

BFE>len<centimeter>
BFE>и
BFE>len<meter>
BFE>- это две разные переменные типа int.

Тогда по вашей логике имена переменных могут включать пробелы, переносы строк, комментарии, макросы и прочее.
Можно же и так записать:
len<   /* пишем пишем*/
   centimeter
  > = 0;


Просто это не переменные а две специализации шаблона переменной, состоящие из имени шаблона и списков параметров шаблона, заключенных в угловые скобки.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Отредактировано 30.09.2015 17:01 VTT . Предыдущая версия .
Re[3]: Чудны способности твои, о стандарт !
От: Went  
Дата: 30.09.15 17:18
Оценка:
Здравствуйте, B0FEE664, Вы писали:
BFE>
BFE>void fun()
BFE>{
BFE>    std::cout << TT("asdf") << std::endl;
BFE>}
BFE>

BFE>Можно ли сделать так, чтобы была создана глобальная переменная содержащая список всех таких строк. Это может быть полезно при переводе сообщений на другой язык.
А что мешает определить TT как вызов функции, внутри которой живет глобальная переменная и дальше по тексту? Или нужна подстановка без поиска в словаре?
Re[4]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 30.09.15 17:26
Оценка:
Здравствуйте, Went, Вы писали:

BFE>>
BFE>>void fun()
BFE>>{
BFE>>    std::cout << TT("asdf") << std::endl;
BFE>>}
BFE>>

BFE>>Можно ли сделать так, чтобы была создана глобальная переменная содержащая список всех таких строк. Это может быть полезно при переводе сообщений на другой язык.
W>А что мешает определить TT как вызов функции, внутри которой живет глобальная переменная и дальше по тексту? Или нужна подстановка без поиска в словаре?

А откуда в этой функции известно, что строка "asdf" вообще существует?
И каждый день — без права на ошибку...
Re[4]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 30.09.15 17:37
Оценка: :)
Здравствуйте, VTT, Вы писали:

VTT>Тогда по вашей логике имена переменных могут включать пробелы, переносы строк, комментарии, макросы и прочее.

Кстати, да!

VTT>Можно же и так записать:

VTT>
VTT>len<   /* пишем пишем*/
VTT>   centimeter
  >> = 0;
VTT>


VTT>Просто это не переменные а две специализации шаблона переменной, состоящие из имени шаблона и списков параметров шаблона, заключенных в угловые скобки.

В том-то и дело, что тип таких переменных не зависит от их специализации. Просто у этих переменных имена сложные, составные.
И каждый день — без права на ошибку...
Re[5]: Чудны способности твои, о стандарт !
От: Went  
Дата: 30.09.15 18:59
Оценка:
Здравствуйте, B0FEE664, Вы писали:
BFE>А откуда в этой функции известно, что строка "asdf" вообще существует?
В смысле, что это строковой литерал, а не результат вызова (std::string("fu") + std::string("ck")).c_str()?
Re[5]: Чудны способности твои, о стандарт !
От: Went  
Дата: 30.09.15 19:08
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:
VTT>>Просто это не переменные а две специализации шаблона переменной, состоящие из имени шаблона и списков параметров шаблона, заключенных в угловые скобки.
BFE>В том-то и дело, что тип таких переменных не зависит от их специализации. Просто у этих переменных имена сложные, составные.
Ну, вроде бы шаблоны переменных вводили для типизированных констант и разных трейтов? Фактически, синтаксический сахар над:
// Вместо
template <typename F>
struct pi_traits
{
  static F get() {return (F)3.1415...;}
};
// Получаем:
template <typename F>
static const pi<F> = (F)3.1415...;

Не? Есть еще какие-то принципиально новые применения?
Re[6]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 30.09.15 21:30
Оценка: 36 (2)
Здравствуйте, Went, Вы писали:

VTT>>>Просто это не переменные а две специализации шаблона переменной, состоящие из имени шаблона и списков параметров шаблона, заключенных в угловые скобки.

BFE>>В том-то и дело, что тип таких переменных не зависит от их специализации. Просто у этих переменных имена сложные, составные.
W>Ну, вроде бы шаблоны переменных вводили для типизированных констант и разных трейтов? Фактически, синтаксический сахар над:
Это, да, но результат чудной.

W>Не? Есть еще какие-то принципиально новые применения?


А вот, только что придумал:
#include <iostream>
     
     
template<class T>
T x = T{};

void f()
{
    class Test{ public: Test(){std::cout << "Test\n";} };

    Test t = x<Test>;
}


int main()
{
    std::cout << "start\n";

    return 0;
}


Какой, думаете, будет вывод такой программы?

Похоже, что можно, таки, заставить выполнятся локальный код в глобальном пространстве. Возможно, что так было всегда, просто синтаксического сахара для мозгов не хватало...
И каждый день — без права на ошибку...
Re[7]: Чудны способности твои, о стандарт !
От: Evgeny.Panasyuk Россия  
Дата: 30.09.15 22:05
Оценка: :)
Здравствуйте, B0FEE664, Вы писали:

BFE>Какой, думаете, будет вывод такой программы?


Clang на Coliru выдал segfault.
Re[3]: Чудны способности твои, о стандарт !
От: Evgeny.Panasyuk Россия  
Дата: 30.09.15 22:19
Оценка: 3 (2) +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Допусти, что все строки в программе обрамлены макросом:

BFE>
BFE>void fun()
BFE>{
BFE>    std::cout << TT("asdf") << std::endl;
BFE>}
BFE>

BFE>Можно ли сделать так, чтобы была создана глобальная переменная содержащая список всех таких строк. Это может быть полезно при переводе сообщений на другой язык.

Если трюк описанный выше соответствует стандарту, то получается что-то типа:
#include <iostream>
#include <vector>

using namespace std;

vector<const char *> strings;

template<class T>
T run_it = T{};

#define GETTEXT(x) \
    [] \
    { \
        struct Action { Action() { strings.push_back(x); } };\
        (void)run_it<Action>; \
        return x; \
    }() \
/**/

void not_used()
{
    const char *x = GETTEXT("first");
    auto y = GETTEXT("second");
}

int main()
{    
    for(auto x : strings)
        cout << x << endl;
}
LIVE DEMO on Coliru GCC:
first
second
Re[8]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 01.10.15 08:34
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

BFE>>Какой, думаете, будет вывод такой программы?

EP>Clang на Coliru выдал segfault.
ideone выдаёт

Test
start


Пойду, посмотрю, что по этому поводу говорит стандарт.
PS Ничего криминального не нашёл. Вроде бы пример корректный.
И каждый день — без права на ошибку...
Отредактировано 01.10.2015 9:20 B0FEE664 . Предыдущая версия .
Re[8]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 01.10.15 09:30
Оценка: 14 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

BFE>>Какой, думаете, будет вывод такой программы?

EP>Clang на Coliru выдал segfault.
Возможно это связано с инициализацией std::cout.

вот так работает
И каждый день — без права на ошибку...
Re[4]: Чудны способности твои, о стандарт !
От: T4r4sB Россия  
Дата: 01.10.15 09:35
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Если трюк описанный выше соответствует стандарту, то получается что-то типа:


Объясните мне, пожалуйста, в какой момент выполняется код добавления строки в хранилище.
При инициализации глобальной переменной run_it<Action>? А код в неиспользуемой функции как бы говорит, что такая глобальная перемення существует?

Забавно, из локального блока объявить глобальную переменную.
Отредактировано 01.10.2015 9:37 T4r4sB . Предыдущая версия .
Re[5]: Чудны способности твои, о стандарт !
От: B0FEE664  
Дата: 01.10.15 10:12
Оценка:
Здравствуйте, T4r4sB, Вы писали:

EP>>Если трюк описанный выше соответствует стандарту, то получается что-то типа:

TB>Объясните мне, пожалуйста, в какой момент выполняется код добавления строки в хранилище.
TB>При инициализации глобальной переменной run_it<Action>?
да.
TB> А код в неиспользуемой функции как бы говорит, что такая глобальная перемення существует?
да, можно и так сказать.

TB>Забавно, из локального блока объявить глобальную переменную.

Забавно не это, а то, что можно выполнить кусочек локального кода из вне.
И каждый день — без права на ошибку...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.