В общем так. написал аналог std::any, свой, собственный (когда ещё std::any не было на моей платформе). Назовём его Any. Проблема в том, чтобы можно было инициализировать std::vector<Any> через фигурные скобочки. Но это нифига не выходит, потому что нужно вводть шаблонный конструктор, а он заменяет собой конструктор копирования по умолчанию. Как задавить? Пока я додумался только до friendly шаблонного класса со специализациями, который вызывает нужную функцию инициализации.
Здравствуйте, Molchalnik, Вы писали:
M>Но это нифига не выходит, потому что нужно вводть шаблонный конструктор, а он заменяет собой конструктор копирования по умолчанию.
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, Molchalnik, Вы писали:
M>>Но это нифига не выходит, потому что нужно вводть шаблонный конструктор, а он заменяет собой конструктор копирования по умолчанию.
NB>это, естественно, не так.
приведённый на колиру пример посмотри. везде печатает "template"
мне всегда казалось, что если перегрузка функции задана в одной единице транлсяции с шаблонной, то при совпадении типов сработает перегрузка. Но в приведённом примере всё наоборот. Если бы я понимал, почему перегрузка не давит шаблонный вариант, я бы и не задавал вопрос.
Здравствуйте, Molchalnik, Вы писали:
M>>>Но это нифига не выходит, потому что нужно вводть шаблонный конструктор, а он заменяет собой конструктор копирования по умолчанию.
NB>>это, естественно, не так.
M>приведённый на колиру пример посмотри. везде печатает "template"
очевидно, в примере ошибка
подсказка, выводи типы параметров.
Здравствуйте, night beast, Вы писали:
M>>приведённый на колиру пример посмотри. везде печатает "template"
NB>очевидно, в примере ошибка NB>подсказка, выводи типы параметров.
я поправил ошибку, с темплейтом в конструкторе по умолчанию и заданием функции вместо созданием Any с конструктором по умолчанию
проблема осталась. хотя подключился move-конструктор
Здравствуйте, Molchalnik, Вы писали:
NB>>очевидно, в примере ошибка
M>я поправил ошибку, с темплейтом в конструкторе по умолчанию и заданием функции вместо созданием Any с конструктором по умолчанию M>проблема осталась. хотя подключился move-конструктор
NB>>подсказка, выводи типы параметров.
чтобы поключился не мув, нужен и не конст копи к-тор.
Здравствуйте, Molchalnik, Вы писали:
M>В общем так. написал аналог std::any, свой, собственный (когда ещё std::any не было на моей платформе). Назовём его Any. Проблема в том, чтобы можно было инициализировать std::vector<Any> через фигурные скобочки. Но это нифига не выходит, потому что нужно вводть шаблонный конструктор, а он заменяет собой конструктор копирования по умолчанию. Как задавить? Пока я додумался только до friendly шаблонного класса со специализациями, который вызывает нужную функцию инициализации.
M>upd. набрал пример на колиру второпях — исправил.
Добавь
Здравствуйте, Molchalnik, Вы писали:
M>Но это нифига не выходит, потому что нужно вводть шаблонный конструктор, а он заменяет собой конструктор копирования по умолчанию. Как задавить?
эта стандартная проблема имеет стандартное решение
#include <iostream>
using namespace std;
struct Any {
Any( ) {cout << "\ndefault";}
template <typename Tn, typename = std::enable_if_t<!std::is_convertible<Tn, Any>::value>> Any( Tn && ) {cout << "\ntemplate";}
Any( const Any & ) {cout << "\ncopy";}
Any( Any&& ) {cout << "\nmove";}
};
int main() {
Any x0;
Any x1( x0 );
Any x2( std::move(x0) );
Any x3( 3 );
return 0;
}
проблема не в том, что заменяется конструктор копирования. Просто для неконстантного объекта лучшим соответствием считается шаблонный конструктор. Если в примере поставить Any const x0 то всё будет также работать — конструктор вызовется
Здравствуйте, sergii.p, Вы писали:
SP>эта стандартная проблема имеет стандартное решение
может не сработать на старых реализациях, т.к. неиспользуемые шаблонные параметры с дефолтным значением в старых версиях стандарта в SFINAE не участвуют.
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, Molchalnik, Вы писали:
M>>Но это нифига не выходит, потому что нужно вводть шаблонный конструктор, а он заменяет собой конструктор копирования по умолчанию. Как задавить?
BFE>Почему: BFE>
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, sergii.p, Вы писали:
SP>>эта стандартная проблема имеет стандартное решение
NB>может не сработать на старых реализациях, т.к. неиспользуемые шаблонные параметры с дефолтным значением в старых версиях стандарта в SFINAE не участвуют.
если не сработает, тогда и надо думать Как минимум это решение для данной проблемы пропагандирует Джосаттис.
Здравствуйте, Molchalnik, Вы писали:
M>В общем так. написал аналог std::any, свой, собственный (когда ещё std::any не было на моей платформе). Назовём его Any. Проблема в том, чтобы можно было инициализировать std::vector<Any> через фигурные скобочки. Но это нифига не выходит, потому что нужно вводть шаблонный конструктор, а он заменяет собой конструктор копирования по умолчанию. Как задавить? Пока я додумался только до friendly шаблонного класса со специализациями, который вызывает нужную функцию инициализации.
Я совсем не понял проблему и что тебе не нравится. Попробуй убрать вот так:
K>Это prefect forwarding, а не шаблонный конструктор, тебе не надо в этом случае переопределять копирование и перемещение.
выяснилось что по умолчанию дефаултовый конструктор для не-конст ссылки не создается, и эта версия имеет большее соответствие, чем сгенерированный автоматически копи к-тор.
K>Это prefect forwarding, а не шаблонный конструктор, тебе не надо в этом случае переопределять копирование и перемещение.
Надо в связи с особенностями реализации
конструктор Any{int} и Any{Any &&} работает совершенно по-разному в моём коде. разве что шаблонный класс-хелпер-инициализатор со специализациями сделать вместо конструктора — и передавать из универсального шаблонного конструктора в него — но это сложно и поэтому убого выглядит
Здравствуйте, Molchalnik, Вы писали:
I>>Добавь I>>
I>>Any( Any& ) {printf("\ncopy2");}
I>>
M>спасибо. поставил плюсик. а почему не происходит best fit на const Any& ? В каком разделе стандарта можно прочитать?
Это особый вид ссылок, известный под кодовым названием Forwarding references. Когда ты используешь для конструирования lvalue выражение, параметр с типом "Тn &&" отображается на тип "Any& &&" (да-да, ссылка на ссылку). После этого происходит так называемый коллапсинг избыточных ссылок, по описанному в стандарте правилу, и получается конечный тип формального параметра "Any&". И этот тип лучше подходит для неконстантного объекта, чем "const Any&".
Здравствуйте, Molchalnik, Вы писали:
M>Надо в связи с особенностями реализации
Ты не понимаешь что тебе надо и зачем.
M>конструктор Any{int} и Any{Any &&} работает совершенно по-разному в моём коде. разве что шаблонный класс-хелпер-инициализатор со специализациями сделать вместо конструктора — и передавать из универсального шаблонного конструктора в него — но это сложно и поэтому убого выглядит
Ну так перегрузи его
Здравствуйте, Kernan, Вы писали:
M>>конструктор Any{int} и Any{Any &&} работает совершенно по-разному в моём коде. разве что шаблонный класс-хелпер-инициализатор со специализациями сделать вместо конструктора — и передавать из универсального шаблонного конструктора в него — но это сложно и поэтому убого выглядит K>Ну так перегрузи его K>
K>делай везде префект порвардинг и не будет лишних копирований.
Настало время вредных советов? Бездумное применение perfect forwarding — это современный изощренный способ стрельбы по собственным конечностям, а тем более, если ВЕЗДЕ.
И кстати, в твоем примере это никакой не perfect forwarding, а просто rvalue ссылка на объект initializer_list. Который, даже сам являясь времменным объектом, предоставляет доступ к своим элементам исключительно по константным lvalue ссылкам. Поэтому перемешение содержимого initializer_list невозможно в принципе. Пруф здесь.