Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Конструктор перемещения замещается шаблонным конструктором / 8 сообщений из 8, страница 1 из 1
30.12.2019, 15:57
    #39909932
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Конструктор перемещения замещается шаблонным конструктором
Всех с наступающим!

Столкнулся с проблемой. Компилятор VS2019/VS2017 выбирает не тот конструктор при попытке скомпилировать код:

Код: 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.
30.
struct Base
{
	template <typename FuncT, typename ... ArgsT>
	explicit Base(FuncT&& fn, ArgsT&&... vArgs)
	{
	
		std::invoke(fn, std::forward<ArgsT>(vArgs)...);
	}

	Base(Base&& other) noexcept
	{
		// какой-нибудь полезный код
	}
};

struct Derived : public Base
{
	template <typename FuncT, typename ... ArgsT>
	explicit Derived(bool bFlag, FuncT&& fn, ArgsT&&... vArgs) : Base(std::forward<FuncT>(fn), std::forward<ArgsT>(vArgs))
	{
		m_flag = bFlag;
	}

	Derived(Derived&& other) noexcept : Base(std::move(other)) // проблема здесь!
	{
		// какой-нибудь полезный код
	}

	bool m_flag;
};


Проблема в том, что в Base классе есть шаблонная функция (так называемый универсальный конструктор), которая, по мнению компилятора, лучше подходит для использования в конструкторе перемещения Derived : Base (std::move(other)), хотя по правилам языка победить должна нешаблонная функция при совпадающих/подходящих аргументах. Так?

Данный пример приведен только для иллюстрации проблемы, реальный код несколько сложнее и я не могу написать = default для Derived и Base конструкторов перемещения. И не факт что это поможет.

Есть ли способ убедить компилятор использовать конструктор перемещенния Base , а не универсальный конструктор Base из конструктора перемещения Derived ?

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

https://godbolt.org/z/ER48Ml

--------------------------------------------------------------
o(O_O)o
...
Рейтинг: 0 / 0
30.12.2019, 16:31
    #39909952
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Конструктор перемещения замещается шаблонным конструктором
Cerebrum,

Попробуйте так
Код: plaintext
1.
2.
3.
4.
5.
	explicit Base(FuncT/*&&*/ fn, ArgsT&&... vArgs)
	{
	
		std::invoke(std::move(fn), std::forward<ArgsT>(vArgs)...);
	}
...
Рейтинг: 0 / 0
30.12.2019, 16:36
    #39909957
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Конструктор перемещения замещается шаблонным конструктором
сработало, спасибо
...
Рейтинг: 0 / 0
30.12.2019, 16:38
    #39909959
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Конструктор перемещения замещается шаблонным конструктором
Cerebrum,

В GCC кстати тоже самое.
Я не вникал почему, т.к. нет времени.
...
Рейтинг: 0 / 0
30.12.2019, 16:50
    #39909967
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Конструктор перемещения замещается шаблонным конструктором
Быстрый гуглеж показал что универсальные ссылки (template + &&) имеют приоритет при выборе перегрузки.
...
Рейтинг: 0 / 0
30.12.2019, 16:54
    #39909971
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Конструктор перемещения замещается шаблонным конструктором
Anatoly Moskovsky
Быстрый гуглеж показал что универсальные ссылки (template + &&) имеют приоритет при выборе перегрузки.

ясно, и это странно, как по мне
...
Рейтинг: 0 / 0
30.12.2019, 17:06
    #39909978
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Конструктор перемещения замещается шаблонным конструктором
Cerebrum
сработало, спасибо

че то я поспешил, в тестовом примере заработало, а вот в рабочем коде, увы, нет
на наводку я получил, буду искать дальше сам
...
Рейтинг: 0 / 0
30.12.2019, 18:57
    #39910039
Z axis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Конструктор перемещения замещается шаблонным конструктором
Meyers, «Effective Modern C++»: Item 26: Avoid overloading on universal references., Item 27: Familiarize yourself with alternatives to
overloading on universal references.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Конструктор перемещения замещается шаблонным конструктором / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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