Is std::ofstream movable? - c++

I have this map which compiles fine in MSVC10 :
std::map<std::string, std::ofstream> m_logFiles;
But on ubuntu using g++ 4.5 with C++0x enabled, I get the following error message :
/usr/include/c++/4.5/bits/ios_base.h|785|error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
By using pointers instead of objects, I resolved the problem.
Searching on the web, I learned that streams are not meant to be copied (the why was well explained). But my question is, is std::ofstream a movable type ? If it is, shouldn't it allow its use as a template parameter in the standard containers ?
If yes, then is g++ behind MSVC10 on this point ? (which would explain why it works on MSVC). I know it would be silly to ask compiler writers to fully implement something that isn't even final, but I'm curious regarding the future.
Using g++ 4.6.1 didn't help.
Edit : reading the comments I dug a little bit further and found that the insert is causing the problem, not the declaration of the map.
Reading Cubbi's link I tried the following :
#include <string>
#include <fstream>
#include <map>
using namespace std;
int main()
{
map<string, ofstream> m_logFiles;
ofstream st;
m_logFiles.insert(make_pair<string, ofstream>(string("a"), move(st)));
return 0;
}
But still no luck. g++ complains about the use of b deleted copy constructor.

std::ofstream is movable. This program compiles for me using clang/libc++:
#include <string>
#include <fstream>
#include <map>
int main()
{
std::map<std::string, std::ofstream> m_logFiles;
}
Reference 27.9.1.11 [ofstream.cons].

I asked a similar question earlier, and later found that GCC doesn't seem to support movable fstreams yet (I just tested GCC 4.6.1) as detailed in this answer.

Related

Memory fault when inserting output for an std::basic_ostream instantiation in QNX

I have the following scenario:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <ostream>
class File_ostream final : public std::basic_ostream<char, std::char_traits<char>>
{
};
int main()
{
const std::string input_file{"file_tests/test.txt.gz"};
std::ifstream ifs{input_file, std::ios_base::in | std::ios_base::binary};
File_ostream file_os{};
file_os << ifs.rdbuf(); // Memory fault (core dumped)
}
My program always crashes when inserting output to file_os and creates a core dump.
The code works fine in Linux but not in QNX :\
Do you have any explanation? hint?
The problem is that you are using the default constructor of basic_ostream which, by the standard, does not exist. I have no idea why g++ and QCC compile your code successfully, but they shouldn't.
Anyway, using non standardized functions reveals non standardized behavior, in your case a crash. I don't know if the correct usage of the default constructor is documented anywhere in the gcc docs, but just avoiding it, and using the correct constructor instead, should solve your issue.

Application crash when using library from the program compiled with make

I'm making scientific calculator in command line in c++ for my usage and also for practice. I have a problem with compiling it using cmake with mingw on windows. These are my source files:
main.ccp
#include <iostream>
#include <string>
#include "ExpressionCalculations/ExpressionParser.h"
int main()
{
std::string humanReadableExpression;
std::cout<<"Enter expression\n";
std::getline(std::cin, humanReadableExpression);
std::cout<<humanReadableExpression;
ExpressionCalculations::ExpressionParser parser;
auto&& expression = parser.GenerateRpnExpression(humanReadableExpression);
return 0;
}
ExpressionParser.h
#pragma once
#include <memory>
#include <stack>
#include <string>
#include <unordered_map>
namespace ExpressionCalculations
{
class ExpressionParser
{
public:
std::unique_ptr<std::string> GenerateRpnExpression(std::string &humanReadableExpression);
private:
// other code
};
}
ExpressionParser.cpp
#include <memory>
#include <stack>
#include <string>
#include <unordered_map>
#include <iostream>
#include "ExpressionParser.h"
namespace ExpressionCalculations
{
std::unique_ptr<std::string> ExpressionParser::GenerateRpnExpression(
std::string& humanReadableExpression)
{
std::unique_ptr<std::string> rpnExpression;
*rpnExpression="3456";
return rpnExpression;
}
These are cmake files
main CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (ScientificCalculator_exe)
add_subdirectory(ExpressionCalculations)
add_executable(ScientificCalculator main.cpp)
target_link_libraries(ScientificCalculator ExpressionCalculations)
module CMakeList.txt
set(calculators ExpressionParser.h ExpressionParser.cpp)
add_library(ExpressionCalculations ${calculators})
When I run it , I can see Enter expression and pass input. Then I get Segmentation fault. However when I remove declaration of ExpressionParser and auto&& expression the string is shown, a string can be inputted and shown in the command. I checked configuration question multiple directories under cmake, https://cmake.org/cmake-tutorial/ and https://www.codeproject.com/Articles/1181455/A-CMake-tutorial-for-Visual-Cplusplus-developers but it seems that I correctly made cmake files. I have no idea why it doesn't work. I use the latest mingw64 on windows with default make compilation parameters.
From the cppreference page on unique_ptr:
The class satisfies the requirements of MoveConstructible and MoveAssignable, but not the requirements of either CopyConstructible or CopyAssignable.
In your ExpressionParser::GenerateRpnExpression function you are attempting to copy the unique_ptr out of the function when you should be moving it. Try return std::move(rpnExpression)
After debugging program compiled with just g++ I found the problem. It was misunderstanding of unique_ptr' default constructor behaviour. I thought it would initialize std::string but after reading doc and checking it it does not initialize object and generates nullptr. Then I looked into Scott Myers's Modern Effective C++ how to initialize the unique_ptr. Instead of std::unique_ptr<std::string> rpnExpression; I used auto rpnExpression = std::make_unique<std::string>();. It works like charm. I checked compiling through cmake and there were not any problems.

(Software issue) Can anyone suggest a download that will definitely bring my Mingw32 compiler up to speed?

#include <iostream>
#include <string>
using namespace std;
int main(){
string s = "wassup", newVal = "though";
cout << *(s.insert(s.begin(), newVal.begin(), newVal.end()));
}
This brings up the problem that the return type of string's insert member function is void (error: void value not ignored as it ought to be). This link indicates C++98 returns void but the "new" standard C++11 does indeed return an iterator.
A bit of context, I actually faced this problem earlier. I was/am using CodeBlocks (GCC Compiler Collection) on Windows 7 64-bit and this program gave the same issue (dereferencing void):
#include <iostream>
#include <list>
int main(){
list<int> x = {1,2,3,4};
*(x.insert(++x.begin(), 3, 2));
for(auto c : x)
cout << c;
}
I posted my issue on a different forum and a user pointed out Mingw32 was missing that particular C++11 change, indicating Mingw-w64 does not have this issue. So I went straight to installing Mingw-w64 on Code::Blocks using this guide and the problem was resolved. It's only now I've found out that the overloaded function which takes three iterator parameters STILL returns void.
I'm a little confused as to why Code::Blocks Mingw32 didn't supply a fully updated C++11 standard. Can anyone suggest a download that will definitely bring my compiler up to speed?

Is there a method to use gmpxx.h together with c++98?

Because of my project I need to use c++98 and gmpxx.h:
But even for a simple project, it doesn't work:
#include <gmp.h>
#include <gmpxx.h>
int main()
{
int xrange=5,yrange=5,component=5;
return 0;
}
The error message is:
I tried using the following compiling methods
libc++: support c++11 and thus work
libstdc++: only support c++98 and do not work
Is there a way to use c++98 to implement gmpxx? thank you :)
Detail of errors when using c98++ to implement:
The breaking line is:
cout<<r<<endl;
But it works in c++11:
The error report:

boost split compile issue

I have the following code snippet. I am compiling using the sun studio 12 compiler and have tried boost 1.33 and 1.39
#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>
using namespace boost;
using namespace std;
int main(int argc, char* argv[])
{
string exbyte = "0x2430";
string exbytes = "0x2430,2430";
typedef vector< string > SplitVec;
SplitVec res1 ;
split(res1 , exbyte, is_any_of(",") );
return 0
}
I get the following compile error:
"/bb/source/boost/boost_1_39_0/boost/algorithm/string/iter_find.hpp", line 175: Error, nomatchoverin: Could not find a match for std::vector::vector(boost::transform_iterator, boost::algorithm::split_iterator, boost::use_default, boost::use_default>, boost::transform_iterator, boost::algorithm::split_iterator, boost::use_default, boost::use_default>) needed in boost::algorithm::iter_split, std::string, boost::algorithm::detail::token_finderF>>(std::vector&, std::string &, boost::algorithm::detail::token_finderF>)
If anybody has thoughts on this that would be awesome. Since I am cotemplateing strtok(only kidding)
Other than the missing semi-colon after return 0, which I assume is an unrelated typo, your code compiles fine for me, using gcc 4.3.2.
According to the documentation for boost::split, you're using the function correctly, so I don't think this is a coding error. Are you sure you have boost installed correctly?
Edit: It may be that Boost doesn't support your particular compiler, so parts of boost may not work for you. See here for a list of supported compilers, along with various issues which affect each compiler.
It sounds like your compiler's STL implementation only provides a vector ctor taking vector::iterator's and not any iterator class. You can verify this by taking a look at the vector header file.
You may able to work around this by using STLPort which apparently can be used with Sun Studio 12.