I am trying to compile some code that was originally build in MS Visual Studio C++ 6.0 with Visual Studio 2013.
In the old code the following construct was often used for various data types (here for example for a string):
std::string someString;
someString = ....;
callSomeFunction(someString.begin().base());
So in order to enable the function to edit (in this example the string) the original buffer, the method begin() gets an iterator for it and the method base() returned a pointer to the first element of the buffer.
In the code this is not only used for strings, but for many many other datatypes as well.
Thus I was wondering, if there was a change to the standard library so the base() method is no longer supported?
Is there any replacement for it? Or do I have to change the code here? Since this was used very frequently, I would prefer to find a simpler solution to this.
Currently I get an error like:
Error 3 error C2039: 'base' : is not a member of 'std::_Vector_iterator>>'
base was not standardized for container iterators. It exists for iterator adaptors such as std::reverse_iterator and std::move_iterator. Microsoft had to remove it from their implementation in order to comply with the ISO C++ standard.
To obtain a pointer from a container iterator, simply use &* iter. To get a pointer to the first element of the contiguous array backing a container, use cont.data().
You can just pass in:
callSomeFunction(&someString[0]);
That will be a char*. However, it would be safer and preferred if you could just change the signature of the function to take a std::string& - especially if there's any potential in that function just writing past the end of someString. I realize that's not always possible though.
Related
I have this class :
#include <unordered_map>
class MyClass
{
// Trie node class
struct Node
{
std::unordered_map<char, Node> m_children;
// ...
}; // .....
};
int main()
{
MyClass m;
}
When compiling, I got this errors :
/usr/include/c++/7/bits/stl_pair.h:204:11: error: ‘std::pair<_T1,
_T2>::second’ has incomplete type
_T2 second; /// #c second is a copy of the second object
^~~~~~ AutocompleteModern.cpp:24:12: note: forward declaration of ‘struct Autocomplete::Node’
struct Node
^~~~
I know that if I use a pointer as a value in the hash map, this might work. But I wonder if it's possible to make the code above compile without changing the type the hash map's value. or is it impossible ?
You have a circular loop dependency: You say that m_children should contain Node objects, but at that point the class Node isn't defined (only declared).
You could use pointers (or references) to incomplete types though:
std::unordered_map<char, std::unique_ptr<Node>> m_children;
Note the use of std::unique_ptr, which is used to indicate that the map is the sole owner of the Node objects (and also has the added benefit of some automatic memory management).
It's possible for some containers, but std::unordered_map is not one of them. It might work with some implementations, but the standard doesn't require it to work for std::unordered_map (in fact it says its undefined to do it). So even if it compiled today, with a particular compiler, it might not work tomorrow.
The containers that can be declared with incomplete types are std::forward_list, std::list, and std::vector. So those containers can be used as a member of a class, before the class definition is complete)
But I wonder if it's possible to make the code above compile without changing the type the hash map's value. or is it impossible ?
It is impossible, because the compiler cannot compute a meaningful (and finite) sizeof for that MyClass.
Put yourself in the compiler shoes: it has to compute a layout, and a byte size (as given by sizeof) for MyClass quite early when compiling your code. And it obviously could not.
In C++, for such circularity, you have to use pointers (but you could "hide" them as smart pointers, etc.).
(So this answer is a rationale or an intuition for Some programmer dude's answer)
There is also another (purely "legal") reason: the C++11 standard n3337 forbids that. I leave up to you to check (and find precisely what clause there forbids that).
PS. As commented by songyanyo, you might find some particular C++ standard library implementation where your code is accepted (I guess that on such implementations, more hidden pointers are used). This is not the case on my Linux Debian Sid box (both with GCC 8 and Clang 7). In practice you want to write code that is compilable on your box. I have no idea which particular C++ standard library is the most conforming to the standard, but the intuition above stays.
I am currently writing a gameboy emulator for practicing C++. I have gotten to the part where I implement CPU instructions and decided a vector of std::function was a good choice.
Please note: u8 is an alias for uint8_t.
In my code, there is a vector of std::function<u8()> with three types of members:
A lambda expression that returns u8.
Pointer to a member function.
Pointer to a templated member function.
I tried to use an initalizer list at first, but it didn't work. I later found out that is because I needed a call to std::bind(/*function ptr*/, this); on the pointers, but when calling this on the templated function pointers, I get the following error: no matching function for call to 'bind'. I would like to have an initalizer list, as right now it is a function with successive calls to emplace_back.
Here is the erroring line:
instruction_set.emplace_back(bind(&CPU::OPLoadDualRegister8<B, B>, this)); // 0x40 LD B, B
One interesting thing is that when B is replaced with a literal (e.g. 0x00) it works perfectly. B is a u8 and that is what the template accepts.
So:
Is there any way I can do this less convoluted? (e.g. init lists, std::function with member function ptrs, etc.)
If this is the best way, what do I do about the templated ptrs?
Would it better if I took the template params as args and used std::bind to resolve them (all params are either u8 or u8&.
Any optimization suggestions?
Thanks, Zach.
Okay, there is a lot going on here between your question and the comments. Here are some things I notice right off the bat:
If you are going to index into a vector to decode op codes, you probably shouldn't just emplace_back into the vector in order. Instead grow the vector to its final size, filling it with null values and use the subscript operator to put the functions in. instruction_set[0x40] = ...
Using a switch statement and just calling the functions directly is likely a way better choice. Obviously, don't know the ins and outs of your project, so this may not be possible.
When you say B is u8 do you mean B is variable of type u8? Plain 'ol variables can't be used to instantiate templates. B would have to be a macro, template parameter on the calling function, constexpr variable, or static const (basically known at compile time).
std::bind is never any fun for anyone to use, so you are not alone. I don't think it is the root cause of your issue here, but you should probably prefer binding things using capturing lambdas.
Funnily enough C++'s new hearthrob Matt Godbolt (author of Compiler Explorer) gave a talk on emulating a 6502 in JavaScript last year. It's not exactly an authoritative reference on the subject, but it may be worth a watch if you are interested in emulating old microprocessors.
In the following code, the compiler complains as: struct std::array<double,5ul> has no member named 'assign'. Here, it seems possible. Why is it so? (Compiler: g++ 4.8.2)
#include <array>
int main()
{
std::array<double,5> arr;
arr.assign(4.); // error: has no member named 'assign'
return 0;
}
array::assign() is a Visual Studio extension. You are compiling with g++. Check here standard g++ array
As already mentioned, there simply is no assign member to std::array.
The interesting question now becomes why ? After all, the other containers have an assign member method !
I would note that unlike other containers, std::array has a fixed size. If you use std::vector<T>::assign (which would be a close equivalent), the vector is resized appropriately to match the size of the sequence being assigned; with an array, however, that would be impossible:
what would you do if the sequence being assigned is shorter than the array ?
what would you do if the sequence being assigned is longer than the array ?
this would be counter-intuitive, as the question does not arise for the other containers since their size is just adapted on the fly.
For a similar reason, std::array does not have: reserve, capacity, clear, insert, emplace, erase, push/pop (and variants) or resize. All of them suppose a container which size may vary.
That is very simple, as you can see here there is no assign member function for an std array. There is however a member function called fill you should be able to use.
The assign method it is not a member of std::array. The member fill does what the assign did in TR1.
assign was originally part of std::tr1::array (from the TR1) and was changed to be fill circa the C++0x (now C++11) draft n2798 (2008).
This is not really a Microsoft extension, I would imagine that they have probably maintained this method for compatibility with, and support for tr1 implementations in production (the method implementations are exactly the same).
The Boost library provides a convenience function hash_value which basically just called:
return hash<T>()(key);
As far as I can see, C++11 included std::hash which is pretty similar to boost::hash, but did not include std::hash_value. This requires application code to create a hash object and call it's operator() instead of just calling a convenient function. Is there some reason that std::hash_value was not standardized?
The primary use of the std::hash<T> function is the object used to obtain a hash value from a key in the std::unordered_* group of containers. These will always contain and use a corresponding object, possibly, using the empty base optimization to avoid it taking any memory. In any case, whenever the std::hash<T> type is used, an object is actually around.
Although the function object can be used stand-alone, it is probably rare. Also, for other, similar existing function objects there are no corresponding convenience calling functions: although most of them are wrappers for operators, especially std::less<void*> could be interesting to call stand-alone as you can't use ptr1 < ptr2 (at least, it couldn't be used in C++03 if ptr1 and ptr2 were not part of the same array object). That is, there was no suitable precedence.
Finally, I would guess that the convenience function was simply not part of the proposal: if it isn't proposed and there isn't a really good case to have, nothing will be included into the C++ standard. From the looks of it n1456 seems to be, at least, one revision of the "hash table" proposal and it doesn't include a trace of std::hash_value<T>().
I have a class which I want to expose a list of structs (which just contain some integers).
I don't want the outside to modify these data, just iterate over it and read them
Example:
struct TestData
{
int x;
int y;
// other data as well
}
class IterableTest
{
public:
// expose TestData here
};
now in my code I want to use my class like this:
IterableTest test;
BOOST_FOREACH(const TestData& data, test.data())
{
// do something with data
}
I've already read this article http://accu.org/index.php/journals/1527 about memberspaces.
However, I don't want to (or can't) save all TestData in an internal vector or something.
This is because the class itself doesn't own the storage, i.e. there is actually no underlying container which can be accessed directly by the class. The class itself can query an external component to get the next, previous or ith element, though.
So basically I want my class to behave as if it had a collection, but in fact it doesn't have one.
Any ideas?
It sounds like you have to write your own iterators.
The Boost.Iterator library has a number of helpful templates. I've used their Iterator Facade base class a couple of times, and it's nice and easy to define your own iterators using it.
But even without it, iterators aren't rocket science. They just have to expose the right operators and typedefs. In your case, they're just going to be wrappers around the query function they have to call when they're incremented.
Once you have defined an iterator class, you just have to add begin() and end() member functions to your class.
It sounds like the basic idea is going to have to be to call your query function when the iterator is incremented, to get the next value.
And dereference should then return the value retrieved from the last query call.
It may help to take a look at the standard library stream_iterators for some of the semantics, since they also have to work around some fishy "we don't really have a container, and we can't create iterators pointing anywhere other than at the current stream position" issues.
For example, assuming you need to call a query() function which returns NULL when you've reached the end of the sequence, creating an "end-iterator" is going to be tricky. But really, all you need is to define equality so that "iterators are equal if they both store NULL as their cached value". So initialize the "end" iterator with NULL.
It may help to look up the required semantics for input iterators, or if you're reading the documentation for Boost.Iterator, for single-pass iterators specifically. You probably won't be able to create multipass iterators. So look up exactly what behavior is required for a single-pass iterator, and stick to that.
If your collection type presents a standard container interface, you don't need to do anything to make BOOST_FOREACH work with your type. In other words, if your type has iterator and const_iterator nested typedefs, and begin() and end() member functions, BOOST_FOREACH already knows how to iterate over your type. No further action is required.
http://boost-sandbox.sourceforge.net/libs/foreach/doc/html/boost_foreach/extending_boost_foreach.html
From the Boost FOR_EACH documentation page:
BOOST_FOREACH iterates over sequences. But what qualifies as a sequence, exactly? Since BOOST_FOREACH is built on top of Boost.Range, it automatically supports those types which Boost.Range recognizes as sequences. Specifically, BOOST_FOREACH works with types that satisfy the Single Pass Range Concept. For example, we can use BOOST_FOREACH with: