As I know, we can use ostream_iterator in c++11 to print a container.
For example,
std::vector<int> myvector;
for (int i=1; i<10; ++i) myvector.push_back(i*10);
std::copy ( myvector.begin(), myvector.end(), std::ostream_iterator<int>{std::cout, " "} );
I don't know when and why we use the code above, instead of traditional way, such as:
for(const auto & i : myvector) std::cout<<i<<" ";
In my opinion, the traditional way is faster because there is no copy, am I right?
std::ostream_iterator is a single-pass OutputIterator, so it can be used in any algorithms which accept such iterator. The use of it for outputing vector of int-s is just for presenting its capabilities.
In my opinion, the traditional way is faster because there is no copy, am I right?
You may find here: http://en.cppreference.com/w/cpp/algorithm/copy that copy is implemented quite similarly to your for-auto loop. It is also specialized for various types to work as efficient as possible. On the other hand writing to std::ostream_iterator is done by assignment to it, and you can read here : http://en.cppreference.com/w/cpp/iterator/ostream_iterator/operator%3D that it resolves to *out_stream << value; operation (if delimiter is ignored).
You may also find that this iterator suffers from the problem of extra trailing delimiter which is inserted at the end. To fix this there will be (possibly in C++17) a new is a single-pass OutputIterator std::experimental::ostream_joiner
A short (and maybe silly) example where using iterator is usefull. The point is that you can direct your data to any sink - a file, console output, memory buffer. Whatever output you choose, MyData::serialize does not needs changes, you only need to provide OutputIterator.
struct MyData {
std::vector<int> data = {1,2,3,4};
template<typename T>
void serialize(T iterator) {
std::copy(data.begin(), data.end(), iterator);
}
};
int main()
{
MyData data;
// Output to stream
data.serialize(std::ostream_iterator<int>(std::cout, ","));
// Output to memory
std::vector<int> copy;
data.serialize(std::back_inserter(copy));
// Other uses with different iterator adaptors:
// std::front_insert_iterator
// other, maybe custom ones
}
The difference is polymorphism vs. hardcoded stream.
std::ostream_iterator builds itself from any class which inherits from std::ostream, so in runtime, you can change or wire the iterator to write to difference output stream type based on the context on which the functions runs.
the second snippet uses a hardcoded std::cout which cannot change in runtime.
Related
I'm pretty much trying to make a AddInputEvent but, after a month, can't find a way to turn a local "function from FunctionCallbackInfo"(i'll just call this argf) in to a Persistent Function so that garbage collection doesn't erase the pointers.
Most stakeoverflow threads and example code I can find just say to Cast argf with a Local Function; then to throw that in to a Persistent New. This results in a error: cannot convert 'v8::Local<v8::Function>' to 'v8::Function*'
here is the code, not completely sure why I can't convert it
class inputevnt_feld{
public:
char* call_on;
v8::Persistent<v8::Function> func;
};
int entvcount = -1;
vector<inputevnt_feld> event_calls; //this is pretty much a array of events that we can call later
// in js looks like this "AddInputEvent("string", function);"
void AddInputEvent( const v8::FunctionCallbackInfo<v8::Value>& args ) {
v8::HandleScope handle_scope(args.GetIsolate());
//gotta make sure that we ain't letting in some trojan horse that has nothing in it
if (args[1]->IsFunction() && args[0]->IsString()) {
inputevnt_feld newt;
//converts js string to char array
v8::String::Utf8Value str(args.GetIsolate(), args[0]);
const char* cstr = ToCString(str);
newt.call_on = (char*)cstr;
//here is where the problem is with function casting
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[1]);
newt.func = v8::Persistent<v8::Function>::New(args.GetIsolate(), callback);
//push the new stuff in to even array
event_calls.push_back(newt);
//getting vector array size is too much for my smol brain
//so I'ma just do this myself
entvcount++;
//cout << event_calls[entvcount].call_on << endl; //debug
}
}
Most stakeoverflow threads and example code I can find just say to Cast argf with a Local Function; then to throw that in to a Persistent New
Yes, that's correct. If you know how to read it, the C++ type system is your friend for figuring out the details.
If you look at the definition of v8::PersistentBase<T>::New, you'll see that it takes a T* (for its template type T). If you look at the v8::Local<T> class, you'll see that a way to get a T* from it is to use its operator*. That leads to:
v8::Local<v8::Function> callback = ...Cast(args[1]);
... = v8::Persistent<v8::Function>::New(..., *callback);
Alternatively, you can use the Persistent constructor directly, and pass it the Local without dereferencing it first:
v8::Local<v8::Function> callback = ...Cast(args[1]);
... = v8::Persistent<v8::Function>(..., callback);
Both options are entirely equivalent. Personally I'd prefer the latter as it takes slightly fewer characters to spell out, but that's really the only difference.
(Your current code as posted does something else: it ignores the result of the cast and passes the original args[1] directly to Persistent::New -- that's not going to work.)
Consider the following class:
class Vector{
int dim; //dimension of array v
Complex* v; //Complex is another class
public:
Vector(int dim = 0):dim(dim){(dim)?(v=new Complex[dim]):(v=nullptr);}
Vector(int dim, const Complex* c):dim(dim),v(new Complex[dim]){
for(int i=0;i<dim;i++) v[i]=c[i];}
Vector(const Vector& a):dim(a.dim),v(new Complex[a.dim]){
for(int i=0;i<dim;i++) v[i]=a.v[i];}
~Vector(){if(dim)delete [] v,v=nullptr;}
friend Vector& operator >> (Vector& is,Complex& z){
Vector copie(is);
is.~Vector();
is.Vector::Vector(is.dim+1);}
};
I try to overload the >> operator in order to add elements to v.
My idea was to create a copy, then call dctor and the ctor for the object to
be modified via >> operator.
I'm stuck after getting this error:
In function ‘Vector& operator>>(Vector&, Complex&)’:
main.cc:56:20: error: cannot call constructor ‘Vector::Vector’ directly
is.Vector::Vector(is.dim+1);
I'm not allowed to use containers!!
Please help me!
That's right, you can't call the constructor directly. Probably you want to use placement new.
friend Vector& operator >> (Vector& is,Complex& z){
Vector copie(is);
is.~Vector();
// is.Vector::Vector(is.dim+1);
new(&is) Vector(is.dim + 1);
return is;
}
Even then the code may not be semantically correct.
Having said that, this is not the recommended way to do it for
the last 20 years. Watch this Jon Kalb "Exception-Safe Code, Part
I" for an explanation (the example is almost the same). The
recommended way is to implement this in terms of other operations like
copy or swap.
Minor syntactic detail, operator>> is confusing, use operator<< at worst.
There is no need for calling the destructor and calling the constructor. Steps you can take to make your function work:
Allocate memory to hold the current objects plus the additional object.
Copy the objects from the old memory location to the new memory location.
Delete the old memory.
Associate the newly allocated memory with the input object.
friend Vector& operator>>(Vector& is, Complex& z){
// Allocate memory
Complex* vnew = new Complex[dim+1];
// Copy objects to new memory.
std::copy(is.v, is.v + is.dim, vnew);
vnew[is.dim] = z;
// Delete the old memory.
delete [] is.v;
// Use the new memory
is.v = vnew;
// Increment dim.
is.dim++;
return is;
}
Having said that, I think you are using the wrong function to insert an element to Vector. operator>> is for extracting data from. operator<< is for inserting data to. You should use operator<< to insert an element to a Vector.
friend Vector& operator<<(Vector& is, Complex const& z){
...
}
I've some code that moves an object into another object. I won't need the original, moved object anymore in the upper level. Thus move is the right choice I think.
However, thinking about safety I wonder if there is a way to invalidate the moved object and thus preventing undefined behaviour if someone accesses it.
Here is a nice example:
// move example
#include <utility> // std::move
#include <vector> // std::vector
#include <string> // std::string
int main () {
std::string foo = "foo-string";
std::string bar = "bar-string";
std::vector<std::string> myvector;
myvector.push_back (foo); // copies
myvector.push_back (std::move(bar)); // moves
return 0;
}
The description says:
The first call to myvector.push_back copies the value of foo into the
vector (foo keeps the value it had before the call). The second call
moves the value of bar into the vector. This transfers its content
into the vector (while bar loses its value, and now is in a valid but
unspecified state).
Is there a way to invalidate bar, such that access to it will cause a compiler error? Something like:
myvector.push_back (std::move(bar)); // moves
invalidate(bar); //something like bar.end() will then result in a compiler error
Edit: And if there is no such thing, why?
Accessing the moved object is not undefined behavior. The moved object is still a valid object, and the program may very well want to continue using said object. For example,
template< typename T >
void swap_by_move(T &a, T &b)
{
using std::move;
T c = move(b);
b = move(a);
a = move(c);
}
The bigger picture answer is because moving or not moving is a decision made at runtime, and giving a compile-time error is a decision made at compile time.
foo(bar); // foo might move or not
bar.baz(); // compile time error or not?
It's not going to work.. you can approximate in compile time analysis, but then it's going to be really difficult for developers to either not get an error or making anything useful in order to keep a valid program or the developer has to make annoying and fragile annotations on functions called to promise not to move the argument.
To put it a different way, you are asking about having a compile time error if you use an integer variable that contains the value 42. Or if you use a pointer that contains a null pointer value. You might be succcessful in implementing an approximate build-time code convention checker using clang the analysis API, however, working on the CFG of the C++ AST and erroring out if you can't prove that std::move has not been called till a given use of a variable.
Move semantics works like that so you get an object in any it's correct state. Correct state means that all fields have correct value, and all internal invariants are still good. That was done because after move you don't actually care about contents of moved object, but stuff like resource management, assignments and destructors should work OK.
All STL classes (and all classed with default move constructor/assignment) just swap it's content with new one, so both states are correct, and it's very easy to implement, fast, and convinient enough.
You can define your class that has isValid field that's generally true and on move (i. e. in move constructor / move assignment) sets that to false. Then your object will have correct state I am invalid. Just don't forget to check it where needed (destructor, assignment etc).
That isValid field can be either one pointer having null value. The point is: you know, that object is in predictable state after move, not just random bytes in memory.
Edit: example of String:
class String {
public:
string data;
private:
bool m_isValid;
public:
String(string const& b): data(b.data), isValid(true) {}
String(String &&b): data(move(b.data)) {
b.m_isValid = false;
}
String const& operator =(String &&b) {
data = move(b.data);
b.m_isValid = false;
return &this;
}
bool isValid() {
return m_isValid;
}
}
In C#, you can define a custom enumeration very trivially, eg:
public IEnumerable<Foo> GetNestedFoos()
{
foreach (var child in _SomeCollection)
{
foreach (var foo in child.FooCollection)
{
yield return foo;
}
foreach (var bar in child.BarCollection)
{
foreach (var foo in bar.MoreFoos)
{
yield return foo;
}
}
}
foreach (var baz in _SomeOtherCollection)
{
foreach (var foo in baz.GetNestedFoos())
{
yield return foo;
}
}
}
(This can be simplified using LINQ and better encapsulation but that's not the point of the question.)
In C++11, you can do similar enumerations but AFAIK it requires a visitor pattern instead:
template<typename Action>
void VisitAllFoos(const Action& action)
{
for (auto& child : m_SomeCollection)
{
for (auto& foo : child.FooCollection)
{
action(foo);
}
for (auto& bar : child.BarCollection)
{
for (auto& foo : bar.MoreFoos)
{
action(foo);
}
}
}
for (auto& baz : m_SomeOtherCollection)
{
baz.VisitAllFoos(action);
}
}
Is there a way to do something more like the first, where the function returns a range that can be iterated externally rather than calling a visitor internally?
(And I don't mean by constructing a std::vector<Foo> and returning it -- it should be an in-place enumeration.)
I am aware of the Boost.Range library, which I suspect would be involved in the solution, but I'm not particularly familiar with it.
I'm also aware that it's possible to define custom iterators to do this sort of thing (which I also suspect might be involved in the answer) but I'm looking for something that's easy to write, ideally no more complicated than the examples shown here, and composable (like with _SomeOtherCollection).
I would prefer something that does not require the caller to use lambdas or other functors (since that just makes it a visitor again), although I don't mind using lambdas internally if needed (but would still prefer to avoid them there too).
If I'm understanding your question correctly, you want to perform some action over all elements of a collection.
C++ has an extensive set of iterator operations, defined in the iterator header. Most collection structures, including the std::vector that you reference, have .begin and .end methods which take no arguments and return iterators to the beginning and the end of the structure. These iterators have some operations that can be performed on them manually, but their primary use comes in the form of the algorithm header, which defines several very useful iteration functions.
In your specific case, I believe you want the for_each function, which takes a range (as a beginning to end iterator) and a function to apply. So if you had a function (or function object) called action and you wanted to apply it to a vector called data, the following code would be correct (assuming all necessary headers are included appropriately):
std::for_each(data.begin(), data.end(), action);
Note that for_each is just one of many functions provided by the algorithm header. It also provides functions to search a collection, copy a set of data, sort a list, find a minimum/maximum, and much more, all generalized to work over any structure that has an iterator. And if even these aren't enough, you can write your own by reading up on the operations supported on iterators. Simply define a template function that takes iterators of varying types and document what kind of iterator you want.
template <typename BidirectionalIterator>
void function(BidirectionalIterator begin, BidirectionalIterator end) {
// Do something
}
One final note is that all of the operations mentioned so far also operate correctly on arrays, provided you know the size. Instead of writing .begin and .end, you write + 0 and + n, where n is the size of the array. The trivial zero addition is often necessary in order to decay the type of the array into a pointer to make it a valid iterator, but array pointers are indeed random access iterators just like any other container iterator.
What you can do is writing your own adapter function and call it with different ranges of elements of the same type.
This is a non tested solution, that will probably needs some tweaking to make it compile,but it will give you an idea. It uses variadic templates to move from a collection to the next one.
template<typename Iterator, Args...>
visitAllFoos(std::pair<Iterator, Iterator> collection, Args&&... args)
{
std::for_each(collection.first, collection.second, {}(){ // apply action });
return visitAllFoos(std::forward<Args>(args)...);
}
//you can call it with a sequence of begin/end iterators
visitAllFoos(std::make_pair(c1.begin(), c1,end()), std::make_pair(c2.begin(), c2,end()))
I believe, what you're trying to do can be done with Boost.Range, in particular with join and any_range (the latter would be needed if you want to hide the types of the containers and remove joined_range from the interface).
However, the resulting solution would not be very practical both in complexity and performance - mostly because of the nested joined_ranges and type erasure overhead incurred by any_range. Personally, I would just construct std::vector<Foo*> or use visitation.
You can do this with the help of boost::asio::coroutine; see examples at https://pubby8.wordpress.com/2014/03/16/multi-step-iterators-using-coroutines/ and http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/overview/core/coroutine.html.
I am trying to use a FILE pointer multiple times through out my application
for this I though I create a function and pass the pointer through that. Basically I have this bit of code
FILE* fp;
_wfopen_s (&fp, L"ftest.txt", L"r");
_setmode (_fileno(fp), _O_U8TEXT);
wifstream file(fp);
which is repeated and now instead I want to have something like this:
wifstream file(SetFilePointer(L"ftest.txt",L"r"));
....
wofstream output(SetFilePointer(L"flist.txt",L"w"));
and for the function :
FILE* SetFilePointer(const wchar_t* filePath, const wchar_t * openMode)
{
shared_ptr<FILE> fp = make_shared<FILE>();
_wfopen_s (fp.get(), L"ftest.txt", L"r");
_setmode (_fileno(fp.get()), _O_U8TEXT);
return fp.get();
}
this doesn't simply work. I tried using &*fp instead of fp.get() but still no luck.
You aren't supposed to create FILE instances with new and destroy them with delete, like make_shared does. Instead, FILEs are created with fopen (or in this case, _wfopen_s) and destroyed with fclose. These functions do the allocating and deallocating internally using some unspecified means.
Note that _wfopen_s does not take a pointer but a pointer to pointer - it changes the pointer you gave it to point to the new FILE object it allocates. You cannot get the address of the pointer contained in shared_ptr to form a pointer-to-pointer to it, and this is a very good thing - it would horribly break the ownership semantics of shared_ptr and lead to memory leaks or worse.
However, you can use shared_ptr to manage arbitrary "handle"-like types, as it can take a custom deleter object or function:
FILE* tmp;
shared_ptr<FILE> fp;
if(_wfopen_s(&tmp, L"ftest.txt", L"r") == 0) {
// Note that we use the shared_ptr constructor, not make_shared
fp = shared_ptr<FILE>(tmp, std::fclose);
} else {
// Remember to handle errors somehow!
}
Please do take a look at the link #KerrekSB gave, it covers this same idea with more detail.