2015-10-28 1 views
4

Я хочу, чтобы создать локальный объект некоторых typenameType в шаблонной функции:Почему инициализация моего объекта с переменными аргументами шаблона требует определения конструктора перемещения?

template <typename Type, typename... Args> 
void create_local(Args... args) 
{ 
    Type val(args...); 
} 

Теперь, когда я называю эту функцию без аргументов (где Type является класс с не Copyable члена):

struct T { 
    std::mutex m; 
}; 

int main() 
{ 
    T t;    // OK: No use of move constructor 
    create_local<T>(); // Error: Requires deleted move constructor!!! 
} 

(coliru link)

г ++ (от 4.7.3 до 5.2) не компилировать и требует определения хода конструктора T? clang 3.7 компилируется успешно.

Кроме того, если (1) удалить std::mutex элемент из Т, (2) объявить конструктор по умолчанию для Т, и (3) объявить удален от копирования конструктор для T:

struct T { 
    T() = default; 
    T(const T&) = delete; 
}; 

int main() 
{ 
    T t;    // OK: No use of move constructor 
    create_local<T>(); // OK: No use of move constructor 
} 

все версии G ++ и clang успешно компилируется. Почему g ++ не компилируется для любого типа Type с не скопируемыми членами?

+0

Хм, похоже, ошибка. Интересно, что g ++ скомпилирует приведенное выше, если вы используете скобки, а не круглые скобки для инициализации. – TartanLlama

+0

Прочитав ваш комментарий, я искал GCC Bugzilla и нашел эти отчеты об ошибках: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58089, https://gcc.gnu.org/bugzilla/show_bug .cgi? ID = 59141 –

ответ

1

Согласно комментарий Андрея Zholos в докладе this ошибка:

я наткнулся на эту ошибку, и ошибка 59141 является дубликатом.

Похоже, что пустая пачка параметров расширяется как t ({}), а не t().

В примере 14.5.3p6 имеется аналогичный пример, который указывает, что obj должен быть инициализирован значением (не копируется), а clang принимает этот код.

Смежные вопросы