powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пятничная шабонная магия
25 сообщений из 143, страница 5 из 6
Пятничная шабонная магия
    #39625281
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devНикак не могу разглядеть - в каком месте тут UB?Да никто и не говорил, что UB из-за каста нуля к указателю.
Ты, похоже, вообще не понимаешь, что тебе пишут.Алилуия!
Я надеюсь, п.1 параграфа 4.11 стандарта достаточно доходчиво объясняет что, к чему и как может быть приведено?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625284
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyПохоже нет смысла продолжать. ))Ну еще бы!...
Напомни еще разок, что так к чему приводить - UB? :)
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625347
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyrdb_devЕще не могу понять
Похоже нет смысла продолжать. ))На счёт "deduction" nullptr для выбора void f(char*) соглашусь - вчера затупил... :) Но на счет якобы UB при конвертации (size_t)0 к типизированному указателю на экземпляр структуры/класса/члена совершенно не согласен.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625412
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devНо на счет якобы UB при конвертации (size_t)0 к типизированному указателю на экземпляр структуры/класса/члена совершенно не согласен.
UB не тут. Но смысла дальше объяснять нет, т.к. уже не раз пытались. Кто захотел - понял, а кто не понял тот поймет )))
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625500
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, подытожим? :)
Anatoly Moskovskyrdb_dev"&((C*)0)->Get" - это что? Амперсанд (взятие адреса) видим?
где здесь доступ к члену экземпляра класса (чтение свойства/вызов метода) по нулевому указателю экземпляра?
Согласно стандарту, E1->E2 эквивалентно (*(E1)).E2
Таким образом "->" это в том числе и разыменование указателя.

В стандарте (всех версий), разыменование нулевого указателя упоминается как пример UB. (С++17 8.3.2.5)По очевидным причинам, в личном пользовании у меня нет стандарта C++17, поэтому я пользую draft N4659. Привожу абзац полностью:
" 8.2.5 Class member access [expr.ref]
1 A postfix expression followed by a dot . or an arrow ->, optionally followed by the keyword template (17.2),
and then followed by an id-expression , is a postfix expression. The postfix expression before the dot or arrow
is evaluated; 67 the result of that evaluation, together with the id-expression, determines the result of the
entire postfix expression.

2 For the first option (dot) the first expression shall be a glvalue having complete class type. For the second
option (arrow) the first expression shall be a prvalue having pointer to complete class type. The expression
E1->E2 is converted to the equivalent form (*(E1)).E2 ; the remainder of 8.2.5 will address only the first
option (dot). 68 In either case, the id-expression shall name a member of the class or of one of its base classes.
[ Note: Because the name of a class is inserted in its class scope (Clause 12), the name of a class is also
considered a nested member of that class. — end note ] [ Note: 6.4.5 describes how names are looked up
after the . and -> operators. — end note ]
-------------------------------------
67) If the class member access expression is evaluated, the subexpression evaluation happens even if the result is unnecessary to
determine the value of the entire postfix expression, for example if the id-expression denotes a static member.
68) Note that (*(E1)) is an lvalue."

Никакого доступа к члену класса в данном контексте нет, так как и E1->E2, и (*(E1)).E2, это, всего лишь, место в памяти. Конечно, если упомянутые выражения я использую в неизменном виде как rvalue или lvalue, при том, что в E1 будет nullptr, то получу UB, а на винде даже page fault, но при "evaluation" выражения с оператором взятия адреса (&), rvalue уже не будет являться доступом к экземпляру класса и/или члену экземпляра. Стандарт же не идиоты писали!
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39710236
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я надеваю свой шаблонный плащ и шаблонную шляпу...

Слушайте, можно как-нибудь сделать перечисление/цикл по типам?

К примеру, схематично, надо так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
template <typename T> class C
{
public:
	void Do(void){};
}
vector<typename> types;
types.emplace_back(int);
types.emplace_back(wstring);
types.emplace_back(float);

// somewhere else
for (vector<typename>::const_iterator it = types.cbegin(); it < types.cend(); it++)
{
	C<*it>c;
	c.Do();
}



Это можно сделать с рекурсивными шаблонами, но громоздко получается.

У меня есть некоторые структуры типов данных, которые завязаны на типы, т.е. дублируются по ним (int, float, ...) и почти функционалом не отличаются (atoi, atof, etc.). Но отдельных функций работы с ними много и они большие(циклы, перевызовы других функций, логика разбора), поэтому рекурсивное определение шаблонов тут вообще неудобно делать. Вот и думаю, как бы это сделать. У Александреску вроде было что-то такое в Локи, но не уверен, что оно сильно от рекурсивного объявления отличается.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39710237
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb,

Тебе нужны boost::mpl::vector и boost::mpl::for_each.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39711386
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZ, о, спасибо, не знал, что такое есть. В сопутствующей доке этого не нашёл (в интернете есть).

У меня там основная проблема была в выносе кода в отдельные функции. Всё-таки не поленился и вынес...
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39711398
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb,

Советую к прочтению Advanced Metaprogramming in Classic C++ by Davide Di Gennaro . Там такие финты ушами описаны, после которых и жить не хочется,
когда ты знаешь что где-то это может применяться. У тебя сразу все вопросы отпадут касательно реализации Boost MPL.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39712184
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZТам такие финты ушами описаны, после которых и жить не хочется,
когда ты знаешь что где-то это может применяться. У тебя сразу все вопросы отпадут касательно реализации Boost MPL.
Хм, это интересно :)
Мне где-то попадались финты: люди сделали тетрис в потоке отладки сборки проекта
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39712238
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbNekZ, о, спасибо, не знал, что такое есть. В сопутствующей доке этого не нашёл (в интернете есть).

У меня там основная проблема была в выносе кода в отдельные функции. Всё-таки не поленился и вынес...Если мне не изменяет память, for_each вкрячили в стандарт C++14. В GCC он точно есть.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39712240
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devЕсли мне не изменяет память, for_each вкрячили в стандарт C++14. В GCC он точно есть.
for_each по вектору из типов ?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39712263
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZ,
Цитата из stl_algo.h (#include <algorithm>)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
  /**
   *  @brief Apply a function to every element of a sequence.
   *  @ingroup non_mutating_algorithms
   *  @param  __first  An input iterator.
   *  @param  __last   An input iterator.
   *  @param  __f      A unary function object.
   *  @return   @p __f
   *
   *  Applies the function object @p __f to each element in the range
   *  @p [first,last).  @p __f must not modify the order of the sequence.
   *  If @p __f has a return value it is ignored.
  */
  template<typename _InputIterator, typename _Function>
    _Function
    for_each(_InputIterator __first, _InputIterator __last, _Function __f)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_requires_valid_range(__first, __last);
      for (; __first != __last; ++__first)
	__f(*__first);
      return __f; // N.B. [alg.foreach] says std::move(f) but it's redundant.
    }

...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39712289
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devNekZ,
Цитата из stl_algo.h (#include <algorithm>)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
  /**
   *  @brief Apply a function to every element of a sequence.
   *  @ingroup non_mutating_algorithms
   *  @param  __first  An input iterator.
   *  @param  __last   An input iterator.
   *  @param  __f      A unary function object.
   *  @return   @p __f
   *
   *  Applies the function object @p __f to each element in the range
   *  @p [first,last).  @p __f must not modify the order of the sequence.
   *  If @p __f has a return value it is ignored.
  */
  template<typename _InputIterator, typename _Function>
    _Function
    for_each(_InputIterator __first, _InputIterator __last, _Function __f)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_requires_valid_range(__first, __last);
      for (; __first != __last; ++__first)
	__f(*__first);
      return __f; // N.B. [alg.foreach] says std::move(f) but it's redundant.
    }


Проблема только в том, что это не имеет никакого отношения к теме и существует с допотопных времён.
Здесь-то нужен цикл по вектору типов в compile-time, в то время как обычный std::for_each выполняется в рантайме и не по типам совсем.

boost::mpl::for_each является шаблонным типом, а не функцией.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39734747
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня вопрос про специализацию метода шаблона.

Если делаю так, в заголовке:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
emplate<typename T> class C
{
public:
	C<T>(){} // body in
};

// string impl
template<> C::C<string>()
{}



Всё ок. Но не хочу городить код в описании класса, так как конструктор большой, поэтому хочу вынести описание общего конструктора за скобки:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
emplate<typename T> class C
{
public:
	C<T>();
};

template<typename T>C::C<T>() // body out
{}

// string impl
template<> C::C<string>()
{}


сразу получаю ошибку от линкера, что тело уже определено во всех объектниках, где шаблон используется

если вынести специализацю в cpp(вроде это же явный код, там ему и место) - тоже ошибка линкера, но другая, но смысл тот же, функция уже определена
спасает только внос основного конструктора в описание класса-шаблона.
чую, какой-то абсолютно тупой косяк, но понять не могу

и почему оно собирается, когда специализация находится в заголовочном файле?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39734750
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
template<typename T>C<T>::C() // body out, fixed
{}

И это MS VC++17
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39734755
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbесли вынести специализацю в cppто код для не неё не собирается. Странно.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39734783
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbесли вынести специализацю в cpp(вроде это же явный код, там ему и место)
если хочешь, чтобы конструктор для специализации был в cpp попробуй вынести в cpp
Код: plaintext
1.
template class C<string>;
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39734788
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb,

Ни разу не видел чтобы так кто-то писал. Даже сложно понять чего ты этим хотел добиться
Код: plaintext
1.
2.
3.
4.
5.
template<typename T> class C
{
public:
	C<T>();
};



Это тоже какая-то лажа, у тебя же не template-конструктор, а класс:
Код: plaintext
1.
2.
3.
// string impl
template<> C::C<string>()
{}



Почему не так?
Код: plaintext
1.
2.
3.
// string impl
template<> C<string>::C()
{}



В общем таким должен быть хедер:
Код: plaintext
1.
2.
3.
4.
5.
template<typename T> class C
{
public:
	C();
};



А таким cpp-шник:
Код: plaintext
1.
2.
3.
template<> C<string>::C()
{
}



А заодно, раз уж ты ограничиваешь инстанциации шаблона, то сделай это на уровне компилятора, а не линкера,
либо через SFINAE, либо явным путём всех возможных специализаций всего класса в хедере.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39734810
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZПочему не так?Оно так и есть, просто я торопился :)
NekZВ общем таким должен быть хедер:ну вот оно так не собирается, про это и был воспрос.

NekZА заодно, раз уж ты ограничиваешь инстанциации шаблона, то сделай это на уровне компилятора, а не линкера,
либо через SFINAE, либо явным путём всех возможных специализаций всего класса в хедере.Мне нужно просто переопределить один метод для одного типа(в качестве параметра шаблона). SFINAE, конечно, можно приделать, но это слишком для такой простой ситуации. Мне надо вот, как тут , но код общей функции print вынести из описания класса.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39734812
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZА таким cpp-шник:А, да, если код в cpp - он не собирается, т.е. компилятор его игнорирует.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39734926
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbNekZА таким cpp-шник:А, да, если код в cpp - он не собирается, т.е. компилятор его игнорирует.
Друг, ну что за формулировки? Наверное, ты имел в виду линкер?
Кстати, можно было бы попробовать трюк с extern template.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39735394
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZДруг, ну что за формулировки? Наверное, ты имел в виду линкер?Нет, именно компилятор. Конечного(скомпилированного) кода нет. Если я ставлю в cpp-коде брекпоинт, среда его убирает с формулировкой, что по этому cpp-коду не было ничего собрано. Тогда как брекпоинт в заголовке ставится и отрабатывает - код есть.
NekZКстати, можно было бы попробовать трюк с extern template.Нет, надо разобраться в вопросе :) Там должно быть всё просто. Я сейчас возьму таймаут(много работы) и чуть позже спокойно посмотрю, почему оно так и как оно должно быть. А пока сделаю, чтоб просто работало :}
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39815179
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbЯ сейчас возьму таймаут(много работы) и чуть позже спокойно посмотрю
ты сам в это веришь?У меня вопрос:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
class A1
{
public:
	void fn(const char* s) {}
};
class B1 : public A1
{
public:
	using A1::fn;
public:
	void fn(float f) {}
};
// in far-far gxy:
	B1 b1;
	b1.fn("a?");

вопрос: почему оно не работает без using A1:fn?

При чём тут шаблоны? Когда я пишу класс-шаблон с переменным числом шаблонных параметров, у меня в нём есть одинаковый метод-шаблон, который хочется видеть из всех итераций класса. Но как для него написать using?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39815216
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
код для большего понимания ситуации:

Код: plaintext
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.
// base
template <typename... TS> class Params
{};
// empty
template <> class Params<>
{};
// first
template <typename T1> class Params<T1> : public Params<>
{
public:
	template <typename TE> auto ParamGet(const wstring& name, const TE&) -> enable_if_t<is_same<TE, T1>::value , TE>
	{
		return 0;
	}
};
// iteration
template <typename T1, typename... TS> class Params<T1, TS...> : public Params<TS...>
{
public:
	using Params<TS...>::ParamGet; // и тогда мы видим эти методы в коде, но только не шаблонные, типа:
	//auto ParamGet(const wstring& name, const T1&) -> typename T1
	//{
	//	return 0;
	//}
	template <typename TE> auto ParamGet(const wstring& name, const TE&) -> enable_if_t<is_same<TE, T1>::value, TE>
	{
		return 0;
	}
};



Код: plaintext
1.
2.
3.
4.
5.
6.
// in fr-fr gx
	Params<int, float, wstring> params;
	// work
	wstring str = params.Params<wstring>::ParamGet<wstring>(L"str", L"");
	// wrong, cause c++ standard 13.2
	wstring str2 = params./*Params<wstring>::*/ParamGet<wstring>(L"str", L"");



Вот если ParamGet не шаблон, то using Params<TS...>::ParamGet; добавляет видимости методам из классов-предков, и всё становится ок. Как написать правильный uning, чтобы это работало с шаблонами.

PS: можно написать !is_same<TE, T1> и прокидывать методы из предков, но тогда возникают неприятные предупреждения компилятора о множественных реализациях.

PPS: если до вечера не найду решение, то буду использовать передачу параметра в функцию и неявную специализацию. И страдать от того, что всё в две строчки, а могло быть в одну.
...
Рейтинг: 0 / 0
25 сообщений из 143, страница 5 из 6
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пятничная шабонная магия
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]