Эта проблема основана на коде, который работает у меня на 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
копирование-конструкцию. - Примените предыдущий шаг и к конструкции перемещения.
Итак, если я передам 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 ошибкой из-за конфликта?