Попытка скомпилировать в этот код приводит к ошибке компилятора с «более новыми» компиляторами (я предполагаю: они поддерживают конструкторы перемещения). Что-то вроде «попытки вызвать удаленную функцию».
Оказывается, что компиляция с использованием 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