Ошибка компилятора: требуется только разрешение elision, но конструктор перемещения, кажется, требуется (компилятором) - PullRequest
0 голосов
/ 28 июня 2018

Попытка скомпилировать в этот код приводит к ошибке компилятора с «более новыми» компиляторами (я предполагаю: они поддерживают конструкторы перемещения). Что-то вроде «попытки вызвать удаленную функцию».

Оказывается, что компиляция с использованием gcc 8.1 и clang 6.0.0 при включенном c ++ 17 (что, как считается, связано с функцией "гарантированного разрешения копирования") без ошибок. Однако также выяснилось, что с MSVC 19.14 (также с включенным c ++ 17) происходит сбой, даже если он должен иметь эту функцию (появилось в 19.13). Так это просто ошибка в MSVC, разрешено ли это делать, или это вообще другая функция?

#include <string>
#include <iostream>
#include <sstream>


class A : public std::stringstream {
public:
  A(std::string str) : str_(str) {
  }
  //A(A&&);

  ~A() {
     std::cout << str_;
  }
  std::string str_;
};


A make_A() {
  return A("hello");
}

int test(int num) {
    A test = make_A();
}

Класс «A» - это просто «эксплойт» с разрешением копирования (или RVO - оптимизация возвращаемого значения) и тот факт, что он также не вызывает пользовательский деструктор.

Удивительно, но комментирование в объявлении конструктора перемещения А делает код компиляцией И связью. Так что может показаться, что компилятор сначала «думает», что ему нужна функция, но позже выясняется, что копирование возможно.

Это было предполагаемое поведение - не должно быть необходимости ни в одном из вызовов.

Размещение декларации без реализации больше не является хорошей практикой. Я также ищу лучшее решение.

Обновление: код используется для класса логгера, который при вызове возвращает временный поток строк, который при уничтожении записывает все, что находится в буфере строк. В логгере также есть некоторые дополнительные сведения о том, где регистрироваться, серьезности и т. Д.

Точная ошибка компиляции с gcc 7.3:

<source>: In function 'A make_A()':

<source>:21:19: error: use of deleted function 'A::A(const A&)'

   return A("hello");

                   ^

<source>:7:7: note: 'A::A(const A&)' is implicitly deleted because the default definition would be ill-formed:

 class A : public std::stringstream {

       ^

<source>:7:7: error: use of deleted function 'std::__cxx11::basic_stringstream<_CharT, _Traits,
_Alloc>::basic_stringstream(const std::__cxx11::basic_stringstream<_CharT, _Traits, _Alloc>&) [with
_CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'

In file included from <source>:4:0:

/opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/sstream:734:7: note: declared here

       basic_stringstream(const basic_stringstream&) = delete;

       ^~~~~~~~~~~~~~~~~~

<source>:7:7: error: use of deleted function 'std::basic_ios<_CharT,
_Traits>::basic_ios(const std::basic_ios<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'

 class A : public std::stringstream {

       ^

In file included from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/ios:44:0,

                 from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/ostream:38,

                 from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/iostream:39,

                 from <source>:3:

/opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/bits/basic_ios.h:475:7: note: declared here

       basic_ios(const basic_ios&) = delete;

       ^~~~~~~~~

<source>: In function 'int test(int)':

<source>:25:21: error: use of deleted function 'A::A(const A&)'

     A test = make_A();

                     ^

Compiler returned: 1

1 Ответ

0 голосов
/ 29 июня 2018

MSVC Состояние «Гарантированная копия elision», кажется, глючит даже с последней выпущенной версией MSVC (VS17 версия 15.7.6).

Смотрите, например, эту галочку: https://developercommunity.visualstudio.com/content/problem/217997/guaranteed-copy-elision-incomplete-in-1562.html

ОБНОВЛЕНИЕ: MS исправила проблему с последней версией VS17 15.8.1

...