VS2019, C++17, специализация std::swap
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 16.01.20 07:49
Оценка:
Есть без проблем компилируемый код

namespace std{

template<>
inline void swap(ole_lib::TConnectData2& x1,ole_lib::TConnectData2& x2)
{
 x1.swap(x2);
}//swap

}//nms std


Который перестал компилироваться, когда я в настройках проекта (VS2019) указал С++17.

Error C2912 explicit specialization 'void std::swap<ole_lib::TConnectData2>(ole_lib::TConnectData2 &,ole_lib::TConnectData2 &)' is not a specialization of a function template


Я полез в <utility>, а там со swap какая-та дичь

template <class _Ty, class>
void swap(_Ty& _Left, _Ty& _Right) noexcept(is_nothrow_move_constructible_v<_Ty>&& is_nothrow_move_assignable_v<_Ty>) {
    _Ty _Tmp = _STD move(_Left);
    _Left    = _STD move(_Right);
    _Right   = _STD move(_Tmp);
}


А что это за второй неименованный аргумент у шаблона?

---
А как теперь правильно определять специализацию для std::swap?

Может я и раньше неправильно её определял?

---
Я так понимаю что

namespace std{

inline void swap(ole_lib::TConnectData2& x1,ole_lib::TConnectData2& x2)
{
 x1.swap(x2);
}//swap

}//nms std


это не специализация, а перегрузка функции, которая будет вызываться для классов, производных от ole_lib::TConnectData2 — а мне такое не надо... я правильно понимаю?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: VS2019, C++17, специализация std::swap
От: reversecode google
Дата: 16.01.20 07:51
Оценка: +1
а зачем вы в std пихаете свой своп ?
Re[2]: VS2019, C++17, специализация std::swap
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 16.01.20 07:57
Оценка:
Здравствуйте, reversecode, Вы писали:

R>а зачем вы в std пихаете свой своп ?


Хм. Хороший вопрос.

Наверное потому, что уже не задумываясь пишу std::swap для всего подряд
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: VS2019, C++17, специализация std::swap
От: reversecode google
Дата: 16.01.20 08:06
Оценка: +1
http://www.gotw.ca/publications/mill17.htm
не понятно зачем вы ее вообще специализируете
перегрузите и хватит
но за пихание в стд конечно бить по рукам надо
Re[2]: VS2019, C++17, специализация std::swap
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 16.01.20 08:33
Оценка:
Здравствуйте, reversecode, Вы писали:

R>http://www.gotw.ca/publications/mill17.htm

R>не понятно зачем вы ее вообще специализируете

Дык, научили же так. Лет 15 назад в сети увидел и начал делать так же

R>перегрузите и хватит


Да. Так и поступил.

Тут, на самом деле, всего три проблемных случая (Слава Всевышнему!) — и это просто чудо для моего объема кода.

Все три связанных класса объявил как final — чтобы не было проблем.

Проект собрался, но работает он или нет пока не знаю.

R>но за пихание в стд конечно бить по рукам надо


Ну, спасибо что хоть не по голове ногами

---
Но, все таки, пусть кто-нибудь объяснит — что это за "template<class T,class>"?

Это хрень для выявления корявого кода подобного моему?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Отредактировано 16.01.2020 13:30 DDDX . Предыдущая версия .
Re[3]: VS2019, C++17, специализация std::swap
От: reversecode google
Дата: 16.01.20 09:07
Оценка: 6 (1)
КД>---
КД>Но, все таки, пусть кто-нибудь все таки объяснит — что это за "template<class T,class>"?

КД>Это хрень для выявления корявого кода подобного моему?


msvc имплементация для явной специализации
в других gcc,clang и стандарте такого нет
Re[3]: VS2019, C++17, специализация std::swap
От: Chorkov Россия  
Дата: 16.01.20 10:00
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, reversecode, Вы писали:


R>>http://www.gotw.ca/publications/mill17.htm

R>>не понятно зачем вы ее вообще специализируете

КД>Дык, научили же так. Лет 15 назад в сети увидел и начал делать так же


R>>перегрузите и хватит


КД>Да. Так и поступил.


КД>Тут, на самом деле, всего три проблемных случая (Слава Всевышнему!) — и это просто чудо для моего объема кода.


КД>Все три связанных класса объявил как final — чтобы не было проблем.


КД>Проект собрался, но работает он или нет пока не знаю.


R>>но за пихание в стд конечно бить по рукам надо


КД>Ну, спасибо что хоть не по голове ногами


КД>---

КД>Но, все таки, пусть кто-нибудь все таки объяснит — что это за "template<class T,class>"?

КД>Это хрень для выявления корявого кода подобного моему?


Это специализация (с стиле enable_if), различных стратегий swap, в зависимости от того есть ли конструктор перемещения или только копирования.
И это отступление от стандарта.
Можно было и без введения дополнительного класса в сигнатуру...
Можно было сделать дополнительную ф-ю _Move с дополнительным аргументом шаблона, естак им проще...

// C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\type_traits:2132
        // FUNCTION TEMPLATE swap
#if _HAS_CXX17
template<class _Ty,
    class = enable_if_t<is_move_constructible_v<_Ty>
        && is_move_assignable_v<_Ty>>> inline
#else /* _HAS_CXX17 */
template<class _Ty,
    class = void> inline
#endif /* _HAS_CXX17 */
    void swap(_Ty&, _Ty&)
        _NOEXCEPT_COND(is_nothrow_move_constructible_v<_Ty>
            && is_nothrow_move_assignable_v<_Ty>);
Re[4]: VS2019, C++17, специализация std::swap
От: reversecode google
Дата: 16.01.20 10:23
Оценка:
есть такое но это не похоже, потому что нет всяких = void
да и в других имлементациях этого не видно

к примеру это не скомпилируется без явного указания специализации

template<class T,class>
void CALL(T &t, T &a)
{
}

struct A{int c;}a,b;

int main()
{
    
    CALL(a,b); // CLASS<A,A>(a,b); или нужен =void в шаблон
    return 0;
}
Re: VS2019, C++17, специализация std::swap
От: B0FEE664  
Дата: 16.01.20 10:25
Оценка: 3 (1)
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Есть без проблем компилируемый код

КД>
КД>namespace std{

КД>template<>
КД>inline void swap(ole_lib::TConnectData2& x1,ole_lib::TConnectData2& x2)
КД>{
КД> x1.swap(x2);
КД>}//swap

КД>}//nms std
КД>


Вроде бы это UB

16.5.4.2.1 Namespace std [namespace.std]
1 Unless otherwise specified, the behavior of a C++ program is undefined if it adds declarations or definitions
to namespace std or to a namespace within namespace std.


хотя может для swap и есть исключение, но я так не думаю.

КД>А как теперь правильно определять специализацию для std::swap?

КД>Может я и раньше неправильно её определял?

Я глубоко не разбирался в этом вопросе, только вот знаю, что в стандарт ввели customization point objects.
Описание тут
Я сам не использовал customization point objects, поэтому могу только посоветовать поискать в этом направлении.
И каждый день — без права на ошибку...
Re[2]: VS2019, C++17, специализация std::swap
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 16.01.20 10:41
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Я глубоко не разбирался в этом вопросе, только вот знаю, что в стандарт ввели customization point objects.

BFE>Описание тут

The correct usage of customization points like swap is to first bring the standard swap into scope with a using declaration, and then to call swap unqualified:

using std::swap;
swap(a, b);

One problem with this approach is that it is error-prone. It is all too easy to call (qualified) std::swap in a generic context, which is potentially wrong since it will fail to find any user-defined overloads.


Блин, я только-только изничтожил глобальный "using namespace std" (и не только) и начал явно указывать std::, как опять это объявляется неправильным
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: VS2019, C++17, специализация std::swap
От: rg45 СССР  
Дата: 16.01.20 15:31
Оценка: 1 (1)
Здравствуйте, B0FEE664, Вы писали:


BFE>Вроде бы это UB

BFE>

BFE>16.5.4.2.1 Namespace std [namespace.std]
BFE>1 Unless otherwise specified, the behavior of a C++ program is undefined if it adds declarations or definitions
BFE>to namespace std or to a namespace within namespace std.


И следующим же пунктом идет:

https://timsong-cpp.github.io/cppwp/namespace.constraints#namespace.std-2

Unless explicitly prohibited, a program may add a template specialization for any standard library class template to namespace std provided that (a) the added declaration depends on at least one program-defined type and (b) the specialization meets the standard library requirements for the original template.173


И перегрузка тоже разрешена: https://timsong-cpp.github.io/cppwp/namespace.constraints#namespace.std-7.

Запрещено вводить новые имена. А кастомайзить существущие можно.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: VS2019, C++17, специализация std::swap
От: rg45 СССР  
Дата: 16.01.20 15:32
Оценка:
Здравствуйте, reversecode, Вы писали:

R>но за пихание в стд конечно бить по рукам надо


Это смотря какое пихание: http://rsdn.org/forum/cpp/7636351.1
Автор: rg45
Дата: 16.01.20
.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: VS2019, C++17, специализация std::swap
От: B0FEE664  
Дата: 16.01.20 15:50
Оценка:
Здравствуйте, rg45, Вы писали:

R>И следующим же пунктом идет:

R>https://timsong-cpp.github.io/cppwp/namespace.constraints#namespace.std-2
R>

R>Unless explicitly prohibited, a program may add a template specialization for any standard library class template to namespace std provided that (a) the added declaration depends on at least one program-defined type and (b) the specialization meets the standard library requirements for the original template.173


Я так понял, что any standard library class template — это только для шаблона класса, а не шаблона функции. Я понял не правильно?
И каждый день — без права на ошибку...
Re[4]: VS2019, C++17, специализация std::swap
От: rg45 СССР  
Дата: 16.01.20 15:59
Оценка:
Здравствуйте, B0FEE664, Вы писали:

R>>И следующим же пунктом идет:

R>>https://timsong-cpp.github.io/cppwp/namespace.constraints#namespace.std-2
R>>

R>>Unless explicitly prohibited, a program may add a template specialization for any standard library class template to namespace std provided that (a) the added declaration depends on at least one program-defined type and (b) the specialization meets the standard library requirements for the original template.173


BFE>Я так понял, что any standard library class template — это только для шаблона класса, а не шаблона функции. Я понял не правильно?


Гм... Действительно. Здесь произошло изменение формулировки. В более ранних версиях (4659/4640/2017-03-21), формулировка несколько другая:

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.176


Нужно будет поисследовать этот вопрос более детально. Я думаю, что здесь имеет место изменение формулировок, без изменения выводов по обсуждаемым ключевым вопросам.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: VS2019, C++17, специализация std::swap
От: B0FEE664  
Дата: 16.01.20 16:01
Оценка:
Здравствуйте, rg45, Вы писали:

R>И перегрузка тоже разрешена: https://timsong-cpp.github.io/cppwp/namespace.constraints#namespace.std-7.


Так это через customization point. Я так понимаю, что в C++17 их нет, а в C++20 я ещё не понял, как правильно их использовать. Расскажите?
И каждый день — без права на ошибку...
Re[4]: VS2019, C++17, специализация std::swap
От: rg45 СССР  
Дата: 16.01.20 16:17
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Так это через customization point. Я так понимаю, что в C++17 их нет, а в C++20 я ещё не понял, как правильно их использовать. Расскажите?


Я пока тоже не владею, к сожалению. Тут конфуз вышел с моей привычкой запускать поиск по более pdf файлу, а ссылки давать на более новый онлайн документ. Нарвался впопыхах на сущесвенные изменения.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: VS2019, C++17, специализация std::swap
От: rg45 СССР  
Дата: 16.01.20 17:48
Оценка:
Здравствуйте, B0FEE664, Вы писали:

R>>И перегрузка тоже разрешена: https://timsong-cpp.github.io/cppwp/namespace.constraints#namespace.std-7.


BFE>Так это через customization point. Я так понимаю, что в C++17 их нет, а в C++20 я ещё не понял, как правильно их использовать. Расскажите?


Я тут погуглил немного и, если я все правильно понял, то прикладному разработчику не требуется делать никаких телодвижений, связанных с customization point objects. Эти объекты — внутренняя фишка стандартной библиотеки, обеспечивающая проверку концептов. Все, что требуется разработчику, это просто написать обычную перегрузку для фунции, обозначенной как customization point. Наиболее часто упоминаются такие функции как std::swap, std::begin, std::end.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: VS2019, C++17, специализация std::swap
От: ομικρον  
Дата: 17.01.20 15:01
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Блин, я только-только изничтожил глобальный "using namespace std" (и не только) и начал явно указывать std::, как опять это объявляется неправильным


The template function boost::swap allows the values of two variables to be swapped, using argument dependent lookup to select a specialized swap function if available. If no specialized swap function is available, std::swap is used.

Re: VS2019, C++17, специализация std::swap
От: Erop Россия  
Дата: 17.01.20 16:05
Оценка: 6 (1)
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Я так понимаю что
<…>
КД>это не специализация, а перегрузка функции,
Да, правильно

КД>которая будет вызываться для классов, производных от ole_lib::TConnectData2 — а мне такое не надо... я правильно понимаю?

А это неправильно.
Шаблон подставится в swap( Производный класс )
А явная перегрузка даст swap( ole_lib::TConnectData2 )
Как думаешь, что выберется?.. shuffle:
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: VS2019, C++17, специализация std::swap
От: B0FEE664  
Дата: 17.01.20 16:22
Оценка:
Здравствуйте, ομικρον, Вы писали:

ομι>

ομι>The template function boost::swap allows the values of two variables to be swapped, using argument dependent lookup to select a specialized swap function if available. If no specialized swap function is available, std::swap is used.


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