Эта проблема основана на коде, который работает для меня на GCC-4.6, но не для другого пользователя с CLang-3.0, как в режиме C++ 0x.Конфликт между конструктором копирования и конструктором переадресации
template <typename T>
struct MyBase
{
//protected:
T m;
template <typename Args...>
MyBase(Args&& ...x) : m(std::forward<Args>(x)...) {}
};
Объект MyBase
может принимать любой список аргументов конструктора, пока T
поддерживает, что строительство подписи. Проблема связана со специальными функциями.
- IIUC, шаблон конструктора отменяет автоматически заданный конструктор по умолчанию. Однако, поскольку шаблон может принимать нулевые аргументы, он будет действовать как явно определенный конструктор по умолчанию (если
T
по умолчанию является конструктивным). - IIUC, определение политики копирования-класса игнорирует шаблоны конструктора. Это означает, что в этом случае
MyBase
получит автоматически определенный конструктор копирования (до тех пор, покаT
будет скопирован), который будет транслироватьT
copy-construction. - Применить предыдущий шаг для перемещения.
Так что если я передаю MyBase<T> const &
в качестве единственного аргумента конструктора, который вызвал конструктор, переадресации или имплицитного копирования?
typedef std::vector<Int> int_vector;
typedef MyBase<int_vector> VB_type;
int_vector a{ 1, 3, 5 };
VB_type b{ a };
VB_type c{ b }; // which constructor gets called
Проблема с моим пользователем заключалась в использовании этого базового класса. Компилятор жаловался, что его класс не смог синтезировать автоматически определенный конструктор копирования, потому что он не смог найти соответствие с шаблоном конструктора базового класса. Должен ли он вызывать MyBase
автоматический экземпляр-копир для собственного автоматического копирования-конструктора? Является ли CLang ошибкой для возникновения конфликта?
Интересный вопрос. Я рекомендую сделать sscce (см. Http://sscce.org/), который работает в GCC и не работает в CLang, чтобы помочь нам лучше понять проблему и воссоздать ее самостоятельно. Также, пожалуйста, сообщите нам точное сообщение об ошибке от CLang. –
На самом деле, версия gcc относительно близко к голове (начиная с 20120202) также не принимает этот код. Кажется, что конструктор пересылки подбирается даже для копии. Я не совсем понимаю, почему. Он не связан с «равномерным синтаксисом инициализации»: даже при использовании скобок для последнего объявления он не компилируется. –
Мой код - это то, что я написал десять лет назад для Boost и обновил для C++ 11 на прошлой неделе. Я не знаю, как работать с системой Boost Trac, но вы можете посмотреть [мои изменения] (https://svn.boost.org/trac/boost/changeset/76982) и [текущее состояние] (http : //svn.boost.org/svn/boost/trunk/boost/utility/base_from_member.hpp) файла (в редакции 77031 в этом письме). – CTMacUser