What's the recommended way to convert a string to an array? I'm looking for something like:
template<class T, size_t N, class V>
std::array<T, N> to_array(const V& v)
{
assert(v.size() == N);
std::array<T, N> d;
std::copy(v.begin(), v.end(), d.data());
return d;
}
Does C++11 or Boost provide something like this? How do others do this? Seems silly having to copy/paste this function myself every time I need it in a project.
That seems fine. There isn't such a thing in C++11, and I don't think there is one in Boost either. If you don't want to paste this all over the place, you can just put it in a header and #include that.
Simply calling:
std::copy(v.begin(), v.end(), d.data());
is The way to convert a string to the array. I don't see any advantage of wrapping this into a dedicated "utility" function.
In addition, unless the compiler optimizes it, the performance may degrade with your function: the data will be copied second time when returning the array.
If you really only want convert string to an array, just use .c_str() (and work on char*). It isn't exactly array<> but may suit your needs.
That's fine, maybe with a minor modification in C++11.
template<class T, size_t N, class V>
std::array<T, N> to_array(const V& v)
{
assert(v.size() == N);
std::array<T, N> d;
using std::begin; using std::end;
std::copy( begin(v), end(v), begin(d) ); // this is the recommended way
return d;
}
That way, if you remove the assertion, this function would work even if v is a raw array.
It doesn't work with std::string, but if you're using a C string literal (char const *), C++20 introduces std::to_array for just this sort of thing:
std::array arr {"Hello, world!"};
https://en.cppreference.com/w/cpp/container/array/to_array
Related
I want to multiply and divide all the elements of std::vector by constant in the same way as it is performed in C++ for ordinary types: at least the result should be integer when input vector has integer type and floating-point type otherwise.
I have found the code for multiplication based on std::multiplies and modified it with the replacement std::divides. As the result, the code works but not in the order I want it:
#include <iostream>
#include <vector>
#include <algorithm>
// std::vector multiplication by constant
// http://codereview.stackexchange.com/questions/77546
template <class T, class Q>
std::vector <T> operator*(const Q c, const std::vector<T> &A) {
std::vector <T> R(A.size());
std::transform(A.begin(), A.end(), R.begin(),
std::bind1st(std::multiplies<T>(),c));
return R;
}
// My modification for division. There should be integer division
template <class T, class Q>
std::vector <T> operator/(const std::vector<T> &A, const Q c) {
std::vector <T> R(A.size());
std::transform(A.begin(), A.end(), R.begin(),
std::bind1st(std::divides<T>(),c));
return R;
}
int main() {
std::vector<size_t> vec;
vec.push_back(100);
int d = 50;
std::vector<size_t> vec2 = d*vec;
std::vector<size_t> vec3 = vec/d;
std::cout<<vec[0]<<" "<<vec2[0]<<" "<<vec3[0]<<std::endl;
// The result is:
// 100 5000 0
size_t check = vec[0]/50;
std::cout<<check<<std::endl;
// Here the result is 2
// But
std::vector<double> vec_d;
vec_d.push_back(100.0);
vec_d = vec_d/50;
std::cout<<vec_d[0]<<std::endl;
// And here the result is 0.5
return 0;
}
How can I write my operator correctly ? I thought that std::bind1st would call division by c for each element, but it does the opposite somehow.
EDIT: I understand that I can write a loop, but I want to do a lot of divisions for big numbers, so I wanted it to be faster...
Using std::transform with C++11, I'd suggest making a lambda (see this tutorial) instead of using bind:
std::transform(A.begin(), A.end(), R.begin(), [c](T val) {
return val / c;
});
In my opinion, lambdas are almost always more readable than binding, especially when (like in your case) you're not binding all of the function's parameters.
Although if you're worried about performance, a raw for loop might be slightly faster, as there's no overhead of the function call and creating the lambda object.
According to Dietmar Kühl:
std::transform() may do a bit of "magic" and actually perform better than a loop. For example, the implementation may choose to vectorize the loop when it notices that it is used on a contiguous sequence of integers. It is, however, rather unlikely to be slower than the loop.
auto c_inverse= 1/c;
std::transform(A.begin(), A.end(), R.begin(), [c_inverse](T val) {
return val * c_inverse;
});
Similar to the other post, but it should be mentioned that rather than division, you will most likely see performance gains by multiplying by the inverse.
Why make it only for vectors? Here's a way to make more generic, to work with many types of containers:
template <class container, class Q>
container operator/(const container& A, const Q c) {
container R;
std::transform(std::cbegin(A), std::cend(A), std::back_inserter(R),
[c](const auto& val) {return val / c; });
return R;
}
Sure, it is expected to be a bit slower than with pre-allocation for a vector, since the back_inserter will allocate dynamically as it grows, but well, sometimes it might be appropriate to trade speed for genericity.
Given the following function, taking: a read-only float span (of either dynamic or any static size):
template <long N> void foobar(gsl::span<const float, N> x);
Let's say I have a vector<float>. Passing that as an argument doesn't work, but neither does using gsl::as_span:
std::vector<float> v = {1, 2, 3};
foobar(gsl::as_span(v));
The above does not compile. Apparently gsl::as_span() returns a gsl::span<float>. Besides not understanding why implicit cast to gsl::span<const float> isn't possible, is there a way to force gsl::as_span() to return a read-only span?
Poking around GSL/span.h on the github page you linked to, I found the following overload of as_span that I believe is the one being called here:
template <typename Cont>
constexpr auto as_span(Cont& arr) -> std::enable_if_t<
!details::is_span<std::decay_t<Cont>>::value,
span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>>
{
Expects(arr.size() < PTRDIFF_MAX);
return {arr.data(), narrow_cast<std::ptrdiff_t>(arr.size())};
}
There's lots to digest here, but in particular the return type of this function boils down to span<std::remove_reference<decltype(*arr.data())>, ...>. For your given vector<float> gives span<float,...> because decltype(*arr.data()) is float &. I believe the following should work:
const auto & cv = v;
foobar(as_span(cv));
but can't test it myself unfortunately. Let me know if this works.
as_span is not part of MS/GSL any more, probably because gsl::span was lately aligned to std::span - which you could now use with C++20.
You can use std::as_const to get a const container and create a gsl::span from that (or in your case to use gsl::as_span on it).
foobar(gsl::span<const float>(std::as_const(v)));
Please note that depending on the implementation of foobar it is not necessary to template it. You could also just write
void foobar(gsl::span<const float> x);
Per default the length of the span is dynamic_extent, so spans of any length would be accepted. Of course you would not have the length available during compile time.
while playing and trying to calculate total size of vector I tried something like
vector<double> vd;
auto area = vd.size()* sizeof (vd::value_type);
//Ive seen Stepanov use area as name for this kind of size, idk if he adds the sizeof vd also to area :)
Unfortunately this doesnt work...
I need to use vector<double>::value_type but that makes code less readable.
Can it be made to work? I dont like sizeof vd.front() because it just looks ugly to write front() for this.
EDIT: decltype variants also fit in what I would call ugly category...
I think decltype can be used:
auto area = vd.size() * sizeof(decltype(vd)::value_type);
as you are using auto I assume C++11 is permitted.
Confirmed with g++ v4.7.2 and clang v3.3.
How about a simple helper function?
template <typename Container>
size_t value_size(const Container &)
{
return sizeof(typename Container::value_type);
}
[...]
vector<double> vd;
auto area = vd.size() * value_size(vd);
You could even overload the function so that it works with other containers such as arrays (of course, you would need to wrap size as well).
Ideally, the entire computation could be wrapped into a generic function:
template <typename Container>
size_t area(const Container &c)
{
return c.size() * sizeof(typename Container::value_type);
}
//possible overload for arrays (not sure it's the best implementation)
template <typename T, size_t N>
size_t area(const T (&arr)[N])
{
return sizeof(arr);
}
[...]
std::vector<double> vd;
auto vd_area = area(vd);
double arr[] = { 1., 2. };
auto arr_area = area(arr);
In C++11, you could use decltype(vd[0]):
auto area = vd.size()* sizeof (decltype(vd[0]));
But in the particular scenario, you could just write this:
auto area = vd.size()* sizeof (vd[0]);
Since the expression inside sizeof (and decltype too) will not be evaluated, both will work even if vd is
empty.
This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
How does this “size of array” template function work?
Is there any possibility to implement NARR without a macro in C++ (C++0x)?
const static pair<string,int> data[] = {
{"Montag",1}, {"Dienstag",2}, {"Mittwoch",3}, {"Donnerstag",4},
{"Freitag",5}, {"Samstag",6}, {"Sonntag",7}
};
#define NARR(A) (sizeof(A)/sizeof(*A))
const static map<string,int> german_weekdays(data, data+NARR(data));
A simple function is not possible, because then the [] loses its size-information and becomes just another poiner:
size_t narr(sometype arr[]) { /* won't work */ }
Templates? Overloading? Magic?
It is possible in C++:
template< typename T, std::size_t Size >
std::size_t size(const T (&)[Size])
{
return Size;
}
The advantage of this over the macro solution is that the compiler will cough up a nasty error message if you try to pass a pointer to this.
In C++0x:
#include <iterator>
const static map<string,int> german_weekdays(data, std::end(data));
Also you can use std::begin(data) if you like, for symmetry or genericness[*]. And possibly you can use an initializer list instead of an array anyway...
[*] Although for full genericness, you should probably do:
using std::begin;
using std::end;
begin(data), end(data);
The reason is that the new "range-based for loop" syntax is equivalent to using begin and end without qualification, but with std as an associated namespace for ADL. So as with std::swap, authors of types might provide begin and end functions that are intended to be found via ADL. They probably ought to provide begin() and end() member functions instead, which std::begin and std::end will call. But if they provide something that works with ranged-based for, and doesn't work with your code, then you'll have to have an argument who should change.
I can't test this right now, because I've been away for a while and the latest GCC 4.6 just refused to compile, but constexpr should make short work of the question. Of course, it's better to sidestep this issue using Steve's suggestion.
template< typename T, size_t N >
constexpr size_t narr( T const (&)[ N ] )
{ return N; }
I want to use a cache, implemented by boost's unordered_map, from a dynamic_bitset to a dynamic_bitset. The problem, of course, is that there is no default hash function from the bitset. It doesn't seem to be like a conceptual problem, but I don't know how to work out the technicalities. How should I do that?
I found an unexpected solution. It turns out boost has an option to #define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS. When this is defined, private members including m_bits become public (I think it's there to deal with old compilers or something).
So now I can use #KennyTM's answer, changed a bit:
namespace boost {
template <typename B, typename A>
std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs) {
return boost::hash_value(bs.m_bits);
}
}
There's to_block_range function that copies out the words that the bitset consists of into some buffer. To avoid actual copying, you could define your own "output iterator" that just processes individual words and computes hash from them. Re. how to compute hash: see e.g. the FNV hash function.
Unfortunately, the design of dynamic_bitset is IMHO, braindead because it does not give you direct access to the underlying buffer (not even as const).
It is a feature request.
One could implement a not-so-efficient unique hash by converting the bitset to a vector temporary:
namespace boost {
template <typename B, typename A>
std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs) {
std::vector<B, A> v;
boost::to_block_range(bs, std::back_inserter(v));
return boost::hash_value(v);
}
}
We can't directly calculate the hash because the underlying data in dynamic_bitset is private (m_bits)
But we can easily finesse past (subvert!) the c++ access specification system without either
hacking at the code or
pretending your compiler is non-conforming (BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS)
The key is the template function to_block_range which is a friend to dynamic_bitset. Specialisations of this function, therefore, also have access to its private data (i.e. m_bits).
The resulting code couldn't be simpler
namespace boost {
// specialise dynamic bitset for size_t& to return the hash of the underlying data
template <>
inline void
to_block_range(const dynamic_bitset<>& b, size_t& hash_result)
{
hash_result = boost::hash_value(bs.m_bits);
}
std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs)
{
size_t hash_result;
to_block_range(bs, hash_result);
return hash_result;
}
}
the proposed solution generates the same hash in the following situation.
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
namespace boost {
template <typename B, typename A>
std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs) {
return boost::hash_value(bs.m_bits);
}
}
boost::dynamic_biset<> test(1,false);
auto hash1 = boost::hash_value(test);
test.push_back(false);
auto hash2 = boost::hash_value(test);
// keep continue...
test.push_back(false);
auto hash31 = boost::hash_value(test);
// magically all hash1 to hash31 are the same!
the proposed solution is sometimes improper for hash map.
I read the source code of dynamic_bitset why this happened and realized that dynamic_bitset stores one bit per value as same as vector<bool>. For example, you call dynamic_bitset<> test(1, false), then dynamic_bitset initially allocates 4 bytes with all zero and it holds the size of bits (in this case, size is 1). Note that if the size of bits becomes greater than 32, then it allocates 4 bytes again and push it back into dynamic_bitsets<>::m_bits (so m_bits is a vector of 4 byte-blocks).
If I call test.push_back(x), it sets the second bit to x and increases the size of bits to 2. If x is false, then m_bits[0] does not change at all! In order to correctly compute hash, we need to take m_num_bits in hash computation.
Then, the question is how?
1: Use boost::hash_combine
This approach is simple and straight forward. I did not check this compile or not.
namespace boost {
template <typename B, typename A>
std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs) {
size_t tmp = 0;
boost::hash_combine(tmp,bs.m_num_bits);
boost::hash_combine(tmp,bs.m_bits);
return tmp;
}
}
2: flip m_num_bits % bits_per_block th bit.
flip a bit based on bit size. I believe this approach is faster than 1.
namespace boost {
template <typename B, typename A>
std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs) {
// you may need more sophisticated bit shift approach.
auto bit = 1u << (bs.m_num_bits % bs.bits_per_block);
auto return_val = boost::hash_value(bs.m_bits);
// sorry this was wrong
//return (return_val & bit) ? return_val | bit : return_val & (~bit);
return (return_val & bit) ? return_val & (~bit) : return_val | bit;
}
}