I'm trying to create sub containers of a container through container<\T>(InputIt First, InputIt Last). For example, I have a string s1="AreYouOK".
The expected outputs are
A
Ar
Are
AreY
AreYo
AreYou
AreYouO
Here is my code:
#include <vector>
#include <string>
#include <iostream>
using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;
int main()
{
string s1 = "AreYouOK";
vector<string> v;
for (string::const_iterator iter = s1.begin();
iter != s1.end()-1; ++iter)
{
string s(s1.begin(),iter); // no matching container
s += *iter;
v.push_back(s);
}
for (vector<string>::const_iterator iter = v.begin();
iter != v.end(); ++iter)
{
cout << *iter <<endl;
}
return 0;
}
I expect the commented line
string s(s1.begin(),iter);
to create a substring s of string s1 in range [s1.begin(), iter), since iter is an iterator of s1. However, I was told that there is no matching constructor for initialization.
error: no matching constructor for initialization of 'string'
(aka 'basic_string<char, char_traits<char>, allocator<char> >')
string s(s1.begin(),iter);
^ ~~~~~~~~~~~~~~~
While
string s(s1.begin(),s1.begin+3);
did manage to create a substring.
Why
string s(s1.begin(),iter);
did not work?
Many thanks!
If you look here, for example, you can see that a full error message contains
prog.cpp:19:33: error: no matching function for call to 'std::basic_string<char>::basic_string(std::basic_string<char>::iterator, std::basic_string<char>::const_iterator&)'
which says that it thinks your calling a constructor that takes an iterator and (reference to) const_iterator. There is no such constructor. Since s1 is a non-const object, s1.begin() returns a regular iterator.
There are many ways around this. One of them is to change your loop to
string::const_iterator b = s1.begin();
for (string::const_iterator iter = b;
iter != s1.end()-1; ++iter)
{
string s(b,iter);
...
Here you indeed use two const iterators (see here your expected output).
Edit
Two excellent (and superior) alternatives are:
Use cbegin if you're C++11 enabled (#rici)
Use accumulate, once you get to that algorithm (#PaulMcKenzie)
Related
I'm trying to create a program that filters through speech text, removes any unwanted characters (",", "?", etc., etc.") and then produces a new speech where the words are jumbled based on what words follow or precede them. So for example, if you had the Gettysburg Address:
Four score and seven years ago our fathers brought forth, on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.
my program would take that text, put it into a set of strings. i.e. ["Four","score","and","seven",...."continent,"..."Liberty,"..."equal."] Then it would remove any unwanted characters from each string using c++ .erase and c++ .remove, like "," or "." and capitals. After, you'd have a filtered string like ["four","score","and","seven",...."continent"..."liberty"..."equal."]
After that then the words would be rearranged into a new coherent, funnier speech, like:
"Seven years ago our fathers conceived on men...", etc.
That was just so you know the scope of this project. My trouble at the moment has to do with either using my iterator properly or null terminators.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <set>
#include <iterator> //iterates through sets
#include <algorithm>
using namespace std;
int main() {
set <string> speechSet;
set <string> ::iterator itr; //forgot what :: means. Declares iterator as set
int sum = 0;
int x;
string data;
ofstream out;
string setString;
ifstream speechFile; //declare output file stream object. Unknown type name
speechFile.open("./MySpeech");
if (!speechFile) {
cerr << "Unable to open file " << endl;
exit(1);
}
char unwantedCharacters[] = ".";
while (!speechFile.eof()) {
speechFile >> data; //speechFile input into data
for (unsigned int i = 0; i < strlen(unwantedCharacters); ++i) {
data.erase((remove(data.begin(), data.end(),
unwantedCharacters[i]), data.end())); //remove doesn't delete.
data.end() - 1 = '\0'; //Reorganizes
cout << data << endl;
}
speechSet.insert(string(data));
}
//Go through each string (word) one at a time and remove "",?, etc.
/*for(itr = speechSet.begin(); itr != speechSet.end(); ++itr){
if(*itr == ".")//if value pointed to by *itr is equal to '.'
itr = speechSet.erase(itr);//erase the value in the set and leave blank
cout << " " << *itr;//print out the blank
else{
cout << " " << *itr;
}
}*/
speechFile.close();
return (0);
}
I keep getting an error that says error: no viable overloaded '='. At first I thought it might be due to .end() not being a command for a C++ string, but I checked the documentation and it shouldn't be an issue of mismatched data typed. Then I thought it might have to set the iterator itr equal to the end of the data.
iterator itr = data.end() - 1;
and then dereference that pointer and set it equal to the null terminator
itr* = '\0';
That removed the overload error, but I still had another error use of class template 'iterator' requires template arguments. Let me know if any more clarification is needed.
In the for loop, use auto for iterator so you don't have to specify its type like:
for(auto itr = speechSet.begin(); itr != speechSet.end(); ++itr){
It seems that if I write
#include <random>
std::minstd_rand engine(1);
std::cout << engine;
then this prints out the internal state of the engine (which is a linear congruential generator). Right now the state equals the seed (1), but if I call a random number and print out engine, it returns some large number, which is probably the state.
How do I actually get the state, in a variable?
Use a string stream instead of stdout. Example:
#include <sstream>
...
std::ostringstream os;
os << engine;
string mystate = os.str();
The o in ostringstream is for output.
The state should be last random number generated, which is why there is not an easier way to do this. It's not as ideal as something like int a; a << engine, but it'll have to do. If you need it that often, make the stringstream operation a function (Including perhaps a conversion from string to integer). You can also typedef a pair of engine/integer with the integer being the state, and make a couple of methods so it's autoset every generation call if you need the performance.
If you don't care about the state, and just want it for the future, do
int engineState = engine();
Now you have the state. Though it's not the same as what it was before, it might not matter depending on your use case.
Output from linear congruential RNG is the state. Or, as alreadynoted, use operator<< to output and convert state
Code
#include <random>
#include <iostream>
#include <sstream>
int main() {
auto engine = std::minstd_rand{ 1 };
auto q = engine();
auto os = std::ostringstream{};
os << engine;
auto r = std::stoul(os.str()); // use ul to fit output
std::cout << q << " " << os.str() << " " << r << '\n';
return 0;
}
prints
48271 48271 48271
Alternative might be if particular implementation implements discard properly in O(log2(N)) time, according to paper by F.Brown https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/anl-rn-arb-stride.pdf. In such case you could move one position back, call RNG again and get your state as output.
Compiler and library I use - Visual C++ 2017 15.7 - has not implemented discard in such way, and useless for moving back.
LCGs consist of a simple state that is represented by a single integer.
This means you can treat this pointer as a pointer to an integer.
Below, I have provided an example of a template function that gets
the state (seed) of an engine and even works for classes deriving LCGs.
#include <random>
template <class T, T... v>
T getSeed(std::linear_congruential_engine<T, v...>& rand) {
static_assert(sizeof(rand) == sizeof(T));
return *reinterpret_cast<T*>(&rand);
}
#include <iostream>
int main() {
std::minstd_rand engine(19937);
auto seed = getSeed(engine);
std::cout << sizeof(engine);
std::cout << '\t' << seed;
}
^ This method is way more efficient (x320 times) than serializing through a stream,
or by creating a dummy ostream and specializing std::operator<< for every case.
template<class T, T... v>
using LCG = std::linear_congruential_engine<T, v...>;
#define DummyRandSpec32 uint_fast32_t, 0xDEADBEEF, 0xCAFE, 0xFFFFFFFF
typedef LCG<DummyRandSpec32> DummyRand32; // the same engine type
template<class T, class R>
T* getSeed(R& rand) // getSeed 70:1 nextInt
{ // creating stream is heavy operation
// return rand._M_x; // cannot access private
__dummy_ostream<T> dumdum; // workaround
auto& didey = *reinterpret_cast<DummyRand32*>(&rand);
std::operator<<(dumdum, didey); // specialized
return dumdum.retrieve(); // pointer to state
}
int main() {
std::minstd_rand engine(19937);
std::cout << *getSeed<uint_fast32_t>(engine);
std::cout << std::endl << engine << std::endl;
}
^ Here is ill-coded my first attempt at a solution, if you want to compare.
It is worth mentioning that a field name of the state is implementation-specific.
Purposefully left out std::operator<< and __dummy_ostream.
Sorry for the noob question. I've been immersed in Java for the past while and the book for this course doesn't cover C++.
I have to fill in a function to add keywords (of string type) to an Item object. the prototype of the function is as follows.
void addKeywordsForItem(const Item* const item, int nKeywords, ...);
In Java ... returns the remainder of arguments as a String object and I'm guessing C++ does something similar but I don't know the name of ... so searching for it is rather difficult.
What is ... called and what does it do?
What is ... called and what does it do?
There are multiple places where ... is used in C++. The context in which you are using it, it is called variadic arguments.
The standard header cstdarg provides a type and macros to help you extract specific arguments from variadic arguments.
Example code from http://en.cppreference.com/w/cpp/utility/variadic/va_start:
#include <iostream>
#include <cstdarg>
int add_nums(int count, ...)
{
int result = 0;
va_list args;
va_start(args, count);
for (int i = 0; i < count; ++i) {
result += va_arg(args, int);
}
va_end(args);
return result;
}
int main()
{
std::cout << add_nums(4, 25, 25, 50, 50) << '\n';
}
Short version:
I need to pass a template class a parameter pack, which is the result of applying a function to another parameter pack. This needs to work within a using statement.
Background:
As a challenge, I'm writing a generic C++11 version of python's zip(). In order to do so, I have written a generic zipIterator template class which can be used to iterate over many iterators simultaneously, yielding a tuples of their values. For example:
#include "zip.hpp"
#include <iostream>
#include <vector>
#include <tuple>
int main(){
std::vector<int> vec = {0,1,2,3};
char arr[] = {'a','b', 'c'};
zipIterator<decltype(vec.begin()), char*, decltype(vec.rbegin())>
itr(vec.begin(), std::begin(arr), vec.rbegin());
zipIterator<decltype(vec.begin()), char*, decltype(vec.rbegin())>
end(vec.end(), std::end(arr), vec.rend());
for(; itr!=end; ++itr){
std::cout << "(" << std::get<0>(*itr) << ", " << std::get<1>(*itr)
<< ", " << std::get<2>(*itr) << ")" << std::endl;
}
}
//output:
//(0, a, 3)
//(1, b, 2)
//(2, c, 1)
The Problem
I would like to make a zip container class which can be passed containers, and which zips over them by calling std::begin() and std::end() on each one. So far I have this:
template<typename... Containers>
class zip{
public:
using iterator = zipIterator<???>;
zip(Containers... cs) : begin_(iterator(std::begin(cs)...)),
end_(iterator(std::end(cs)...)){};
iterator begin() {return begin_;}
iterator end() {return end_;}
private:
iterator begin_;
iterator end_;
};
My question is: what goes in the place of ??? to make this work? So far I have tried
std::begin(std::declval<Containers>())...,
decltype(std::begin(Containers)...),
std::result_of<std::begin(Containers)>::type...,
and many more variations on this.
Sorry if this is a repeat. I read the following Stack Overflow answers and they all seem to be related, but I don't think they are quite what I am looking for:
C++11 call member function on template parameter pack of base classes if present
How to make generic computations over heterogeneous argument packs of a variadic template function?
Calling a function for each variadic template argument and an array
using iterator = zipIterator<decltype(std::begin(std::declval<Containers&>()))...>;
The basic idea is that ... expands the pattern on its left. Here, the pattern is decltype(std::begin(std::declval<Containers&>())) - the type of the return value of std::begin when called on an lvalue of type Containers.
I'm trying to use c_escape_ch_p (see here) from boost::spirit to parse an escaped C++ string. But I'm getting a compiler error. Here is my code:
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/home/classic/utility/escape_char.hpp>
#include <boost/spirit/home/classic/utility/confix.hpp>
#include <iostream>
#include <string>
namespace client {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
bool parse(Iterator first, Iterator last) {
using qi::char_;
qi::rule< Iterator, std::string(), ascii::space_type > text;
using namespace boost::spirit::classic;
qi::rule<Iterator, std::string()> myword2 =
confix_p('"', *c_escape_ch_p, '"') ; // ERROR!
text = myword2;
bool r = qi::phrase_parse(first, last, text, ascii::space);
if (first != last)
return false;
return r;
}
}
int main () {
std::string s = "\"foo\"";
bool ok = client::parse(s.begin(), s.end());
std::cout << "OK? " << (ok ? "y" : "n") << std::endl;
return 0;
}
The compiler error is a failed static assert instantiated from the line with confix:
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
So, it says it's not a valid expression. How is it used correctly?
P.S.: I'm using Boost 1.45.
You are trying to combine classic (old, V1, ...) boost::spirit::classic and (new, V2) boost::spirit::qi.
This is not going to work. The newer stuff is a complete, and incompatible, rewrite. See the 'Porting from Spirit 1.8.x' notes in the documentation.
As for the question on how to parse escaped C/C++ strings using boost::spirit::qi, the following article will be helpful:
Parsing Escaped String Input Using Spirit.Qi