initializer_lists of streams (C++11) - c++11

I'm trying to pass variable number of ofstreams over to a function that accepts an initializer_list but doesn't seem to work and throws all possible errors from the initializer_list structure and about how my function is with an array of ofstreams cannot be matched to any defined function.
Is it actually possible to pass a reference of ofstreams over in an initializer_list?
test.cpp
#include "extension.h"
ofstream outputFile, outputFile2;
int main(void) {
outputFile.open(("data_1.txt");
outputFile2.open("data_2.txt");
writeSomething({outputFile, outputFile2});
outputFile.close();
outputFile2.close();
}
extension.h
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <initializer_list>
using namespace std;
void writeSomething(initializer_list<ofstream&> args);
extension.cpp
#include "extension.h"
void writeSomething(initializer_list<ofstream&> args) {
for (auto f : args ) {
f << "hello" << endl;
}
}

clang 3.4 (trunk 194324) produces a pretty clear error message:
initializer_list:54:23: error: 'iterator' declared as a pointer to a
reference of type
'std::basic_ofstream<char> &'
typedef const _E* iterator;
So no, it is not possible. See also Error: forming pointer to reference type 'const std::pair&'… I can't understand this error.
(gcc 4.7.2 and 4.8.1 crashes on this code due to some internal compiler error. I have submitted a bugreport.)
What you could do instead is to pass a pointer instead of a reference, something like this:
#include <fstream>
#include <initializer_list>
using namespace std;
void writeSomething(initializer_list<ofstream*> args) {
for (auto f : args )
*f << "hello" << endl;
}
int main() {
ofstream outputFile("data_1.txt");
ofstream outputFile2("data_2.txt");
writeSomething({&outputFile, &outputFile2});
}
However, I would much rather use a std::vector instead. Using an initializer list for this purpose is very strange and confusing for me.

Related

Why does this std::map not display in a useable way in the watch window of Visual C++?

I'm unable to view certain std::map in the watch window. Looking into the .natvis file, there are multiple implementations for std::map. Is there a way to select one or the other?
https://developercommunity.visualstudio.com/content/problem/1056550/im-unable-to-inspect-a-variable-of-type-stdmap-in.html
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <set>
#include <memory>
typedef std::shared_ptr<std::string> PTR_STRING;
typedef std::map<PTR_STRING, std::size_t> accessFunction2Order;
typedef std::set<accessFunction2Order> setOfAccessFunction2Order;
typedef std::map<std::vector<std::size_t>, setOfAccessFunction2Order> A2B;
typedef std::map<PTR_STRING, std::shared_ptr<A2B> > MAP;
int main()
{ MAP s{
{ std::make_shared<std::string>("asdasdasdasdasdasdasdasdasdasd"),
std::make_shared<A2B>()
}
};
const auto &r1 = *s.begin();
}
The map s cannot be watched (something regarding std::_Tree<> being displayed). Curiously a reference to the first element can.
The problem is caused by a (I think hardcoded) limit in the visual studio debugger.
In order to display one variable, the debugger is adapting what he finds in the .natvis file -- but he gives up after some fixed number of attempts to resolve a type.
The solution to this problem is to use something like std::any
(or boost::any for those of us not blessed with being able to use an uptodate C++ version)
to break this STL type into chunks the debugger can deal with.
This is of course only a workaround.
Let's hope that this problem will be solved soon.
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <set>
#include <any>
#include <memory>
typedef std::shared_ptr<std::string> PTR_STRING;
typedef std::map<PTR_STRING, long> accessFunction2Order;
typedef std::set<accessFunction2Order> setOfAccessFunction2Order;
#if 1
typedef std::map<std::vector<std::size_t>, std::any> A2B;
#else
typedef std::map<std::vector<std::size_t>, setOfAccessFunction2Order> A2B;
#endif
typedef std::map<PTR_STRING, std::shared_ptr<A2B> > MAP;
typedef std::shared_ptr<std::size_t> PTR_INT;
int main()
{ const MAP s{
{ std::make_shared<std::string>("asdasdasdasdasdasdasdasdasdasd"),
std::make_shared<A2B>()
}
};
}

Why including cpp makes different result

l learned "include" keyword are just copy & paste.
But including cpp file makes different compile result.
(gcc6~8 + boost1.69)
// main.cpp
#include <iostream>
// I'll move next code to why.cpp
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
void testFunc()
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
std::string input;
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
// -----------------------------
int main()
{
return 0;
}
Above code compiled without warning.
But, I replace some code with include cpp..
// main.cpp
#include <iostream>
#include "why.cpp" // <----------
int main()
{
return 0;
}
// why.cpp - just copy&paste
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
void testFunc()
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
std::string input;
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
It makes warning [-Wsubobject-linkage]
~~ has a field ~~ whose type uses the anonymous namespace
~~ has a base ~~ whose type uses the anonymous namespace
Please look at this link : https://wandbox.org/permlink/bw53IK2ZZP5UWMGk
What makes this difference?
Your compiler treats the main CPP file specially under the assumption that things defined in it are very unlikely to have more than one definition and so some tests for possible violation of the One Definition Rule are not done inside that file. Using #include takes you outside that file.
I would suggest just not using -Wsubobject-linkage since its logic is based on a heuristic that is not applicable to your code.

Error 2 files include each other

i have this problems while trying to include 2 files each other:
./include/../include/../src/Socket/../LinuxClass/ThreadingPool.hpp:38:5:
error: ‘Client’ does not name a type
Client client;
I already find a solution about declaring the first class in the second files but the error is still there here is the 2 .h
#ifndef THREADINGPOOL_HPP_
#define THREADINGPOOL_HPP_
#include <functional>
#include <algorithm>
#include <queue>
#include "../Socket/Client.hpp"
#include "../Intefaces/IThread.hpp"
#include "Mutex.hpp"
#include "Thread.hpp"
#include "Condvar.hpp"
#include "Process.hpp"
class ThreadingPool {
public:
ThreadingPool(unsigned int num_thr);
~ThreadingPool();
void Add_fct(std::function<void()> job);
private:
enum States {LIVE, DIE};
std::vector<std::thread> thrdVec;
std::vector<States> states;
std::queue<std::function<void()>> jobs;
Mutex mtex;
Condvar cond;
Process pros;
Client client;
};
#endif /* !THREADINGPOOL_HPP_ */
And the second one
#ifndef CLIENT_HPP_
# define CLIENT_HPP_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <functional>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define PORT 1043
#define METASIZE 1024
#include "check_cmd.hpp"
class ThreadingPool;
class Client {
public:
Client();
~Client();
void ifMessage(ThreadingPool * thrdPool);
private:
int csock;
struct sockaddr_in csin;
};
#endif
I think the problem you have is that you put # define (space between hashtag)
instead of #define (no space between hashtag)
i think the space between it causes the compiler to not
implement the code within client.hpp, because you are not getting a error
saying
client.hpp does not exist, instead a error saying client (the class) does not exist. without define being wrote correctly, the compiler pretty much skips past the code within #ifndef

boost locale bad cast exception

The following simple code, compiled with -lboost_locale generates a bad cast exception. It is the same code in the boost tutorial itself. Any help?
#include <boost/locale.hpp>
#include <iostream>
int main()
{
using namespace boost::locale;
date_time now;
std::cout<<as::date<<now<<std::endl;
}
You need to imbue (global) locales:
Live On Coliru
#include <boost/locale.hpp>
#include <iostream>
int main() {
using namespace boost::locale;
boost::locale::generator gen;
std::locale loc = gen.generate(""); // or "C", "en_US.UTF-8" etc.
std::locale::global(loc);
std::cout.imbue(loc);
date_time_period_set things;
date_time now;
std::cout << as::date << now << std::endl;
}
Prints, e.g. on coliru:
09/17/15

Compilation issue with boost range copy of filesystem path

The following code fails to compile with 1.58 while it was compiling with 1.46. I guess it's a type conversion issue, but I can't make it right.
my code
#include <boost/filesystem.hpp>
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <vector>
using namespace boost;
using namespace filesystem;
using namespace adaptors;
int main(int argc, char ** argv)
{
recursive_directory_iterator beg = recursive_directory_iterator(".");
recursive_directory_iterator end = recursive_directory_iterator();
iterator_range<recursive_directory_iterator> files =
make_iterator_range(beg, end);
std::function<bool (path const & path)> fileFilter =
[](path const & path) -> bool {
return is_regular_file(path);
};
std::vector<path> paths;
copy(files | filtered(fileFilter), std::back_inserter(paths));
// works:
//copy(files, std::back_inserter(paths));
// also works:
//for(recursive_directory_iterator it = beg; it != end; ++it){
// if(fileFilter(*it)){
// paths.push_back(*it);
// }
//}
}
Error message (VS2010)
Error 1 error C2664:
'boost::filesystem::recursive_directory_iterator::recursive_directory_iterator(const
boost::filesystem::path
&,boost::filesystem::symlink_option::enum_type)' : cannot convert
parameter 1 from
'boost::iterators::detail::postfix_increment_proxy' to
'const boost::filesystem::path
&' [...]\boost\1.58.0_32\include\boost-1_58\boost\range\concepts.hpp 201 1 [...]
Can anyone help ?
Edit
Filed as https://svn.boost.org/trac/boost/ticket/11228.
This seems to be a bug introduced somewhere since Boost 1.55. Using boost 1.55 this compiles ok.
It could be this bug: https://svn.boost.org/trac/boost/ticket/10989
boost_1_57_0/boost/concept_check.hpp|210 col 13| error: conversion from ‘boost::iterators::single_pass_traversal_tag’ to non-scalar type ‘boost::iterators::forward_traversal_tag’ requested
The filtered adaptor requires the input to be forward_traversal tag. But recursive_directory_iterator only promises single_pass_traversal tag:
BOOST_RANGE_CONCEPT_ASSERT((
Convertible<
BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
forward_traversal_tag
>));
WORKAROUND
You can disable concept checks for now: -DBOOST_RANGE_ENABLE_CONCEPT_ASSERT=0:
Live On Coliru
#include <boost/filesystem.hpp>
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <vector>
#include <iostream>
namespace fs = boost::filesystem;
using namespace boost::adaptors;
int main() {
fs::recursive_directory_iterator beg("."), end;
auto fileFilter = [](fs::path const & path) { return is_regular_file(path); };
std::vector<fs::path> paths;
copy(boost::make_iterator_range(beg, end) | filtered(fileFilter), std::back_inserter(paths));
for(auto& p : paths)
std::cout << p << "\n";
}
Prints
"./main.cpp"
"./a.out"

Resources