I have a lot of error with .append method in c++ - c++

I have a problem with .append methon in C++.
This is my code:
#include<iostream>
#include<string>
using namespace std;
int main(){
char caratteri[] = {"ciao amici"};
string str = "ciao amici";
string token = "";
for(int i = 0; i<str.length(); i++)
{
if(str[i+1] == ' '){
token = "";
}
char current_token = str[i];
token.append(string(current_token));
i++;
}
}
And this is a part of my output:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\basic_string.h:397:7: note: no known conversion for argument 1 from 'char' to 'const std::__cxx11::basic_string<char>&'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\basic_string.h:389:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPT
^~~~~~~~~~~~
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\basic_string.h:389:7: note: no known conversion for argument 1 from 'char' to 'const std::allocator<char>&'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\basic_string.h:380:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string()
^~~~~~~~~~~~
Why have I got this problem? Can I solve it?
Thank you very much :)

You try to create a std::string from a char here:
token.append(
string(current_token) // <- this part
);
To create a std::string from a single char, you need to supply how many times you want the char repeated:
token.append(string(1, current_token));
Fortunately, append has en overload that lets you do that directly, without creating an intermediate std::string:
token.append(1, current_token);
But the easiest would probably be to use the operator+= overload to add a single char:
token += current_token;
Note also that this
if(str[i+1] == ' ')
will access str[str.length()] when i == str.length() - 1. That is accessing it out of bounds. It will probably work anyway because there's a \0 stored just out of bounds, but I recommend that you fix that logic.

Related

GCC problem with static_cast<std::u16string>

Summary
I have a class to which I've added a typecast operator to convert to std::u16string. The signature of this operator looks as follows:
operator const std::u16string() const;
In my .cpp file, I try converting an object of my class's type to std::u16string as follows:
std::u16string sUTF16Password = static_cast<std::u16string>(Password_);
On Visual Studio 2017, this works just fine. However, GCC 6.3 on my Raspberry Pi gives the following error at compile time:
error : call of overloaded 'basic_string(MyClass&)' is ambiguous
What is the right way to write this typecast? Searching on Google brings a lot of hits for character encoding conversions, but that's not my problem here. I don't understand why the basic_string constructor is being called here despite using static_cast.
Full example
Here's a minimal example. Compiling it with g++ main.cpp fails on my Raspberry Pi.
#include <iostream>
#include <string>
class MyClass
{
private:
std::u16string Str;
public:
MyClass() { Str = u"abcd"; }
operator const char16_t*() const { return Str.c_str(); }
operator std::u16string() const { return Str; }
};
int main()
{
MyClass Tester;
std::u16string TestStr = static_cast<std::u16string>(Tester);
for (size_t idx = 0; idx < TestStr.size(); idx++)
std::cout << idx << ": " << TestStr[idx] << std::endl;
return 0;
}
The output of gcc --version is gcc (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516.
The full output from g++ main.cpp is:
main.cpp: In function ‘int main()’:
main.cpp:17:61: error: call of overloaded ‘basic_string(MyClass&)’ is ambiguous
std::u16string TestStr = static_cast<std::u16string>(Tester);
^
In file included from /usr/include/c++/6/string:52:0,
from /usr/include/c++/6/bits/locale_classes.h:40,
from /usr/include/c++/6/bits/ios_base.h:41,
from /usr/include/c++/6/ios:42,
from /usr/include/c++/6/ostream:38,
from /usr/include/c++/6/iostream:39,
from main.cpp:1:
/usr/include/c++/6/bits/basic_string.h:476:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_
CharT, _Traits, _Alloc>&&) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
basic_string(basic_string&& __str) noexcept
^~~~~~~~~~~~
/usr/include/c++/6/bits/basic_string.h:454:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&
) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
^~~~~~~~~~~~
/usr/include/c++/6/bits/basic_string.h:397:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::__cxx11::basic_st
ring<_CharT, _Traits, _Alloc>&) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
basic_string(const basic_string& __str)
^~~~~~~~~~~~
If I remove the typecast to const char16_t* this example compiles just fine. I still don't understand why having both typecasts is a problem.
If you compile as C++14 (or earlier), you'll get this ambiguous call, because std::u16string(char16_t*) participates in the overload resolution (via MyClass::operator const char16_t*()) as well as MyClass::operator std::u16string() that would appear to be a better match.
This can be overcome in several ways:
Compile as C++17 (or later) with GCC 7 or later (sadly, this doesn't help with GCC 6).
Remove operator const char16_t*().
Add explicit to operator const char16_t*() (or to both conversion operators).

How to convert C++ map<string,map<string>> to Php::Value in PHPCPP library?

I'm am creating PHP extension using PHP library, and I am having difficulties converting C++ map variable to PHPCPP Php::Value returned by a function. The reason I'm doing this is to get multidimensional associative array result from a function written in C++.
Is there a way to convert C++ map < string, map < double, map < double, map< double, map< string, map< int, double>>>>>> data to Php::Value in PHPCPP, or is there a better way of dealing with this?
Here is my C++ code:
#include <phpcpp.h>
#include <ctime>
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include <regex>
#include <stdlib.h> /* atof,strtod */
#include <cstddef> // std::size_t
#include <sstream>
#include <vector>
#include <boost/algorithm/string.hpp> // include Boost, a C++ library
#include <boost/regex.hpp>
using namespace std;
double get_curve_rate(string curve_type, double shape, double peak, double tpeak, double lag, string start, string index, double interval) {
double rate = 0.0;
if (curve_type == "t1") {
if ((shape + peak + tpeak) != 0)
rate = 0;
}
else if (curve_type == "t2") {
if ((peak + tpeak + lag) != 0)
rate = 1;
}
return rate;
}
class Curve : public Php::Base
{
public :
string type;
double shape = 0.0;
double peak = 0.0;
double tpeak = 0.0;
double lag = 0.0;
string start;
double interval = 0.0;
int month_no = 0;
string month;
string start_date;
/**
* C++ constructor and destructor
*/
Curve() {}
virtual ~Curve() {}
};
Php::Value get_all_curve_rates(Php::Parameters &params) {
vector<Curve> curves = params[0];
//create an associative array and return to php
map< string, map<double, map<double, map<double, map<string, map<int, double>>>>>> data;
for (auto &c : curves) // access by reference to avoid copying
{
if (c.type == "t1"){}
// data[c.type][c.peak][c.tpeak][c.lag][c.start_date][c.month_no] = get_curve_rate(c.type, c.shape, c.peak, c.tpeak, c.lag, c.start, c.month, c.interval);
else if (c.type == "t2") {}
// data[c.type][c.shape][c.peak][c.tpeak][c.start_date][c.month_no] = get_curve_rate(c.type, c.shape, c.peak, c.tpeak, c.lag, c.start, c.month, c.interval);
}
return data;
}
/**
* Switch to C context, because the Zend engine expects get get_module()
* to have a C style function signature
*/
extern "C" {
/**
* Startup function that is automatically called by the Zend engine
* when PHP starts, and that should return the extension details
* #return void*
*/
PHPCPP_EXPORT void *get_module()
{
// the extension object
static Php::Extension extension("test", "1.0");
// add functions so that they can be called from PHP scripts
// description of the class so that PHP knows which methods are accessible
Php::Class<Curve> curve("Curve");
extension.add("get_all_curve_rates", get_all_curve_rates, {
Php::ByVal("curves", Php::Type::Array),
});
// return the extension details
return extension;
}
}
Compiler gives these errors:
In file included from /usr/include/phpcpp.h:42:0,
from main.cpp:1:
/usr/include/phpcpp/value.h: In instantiation of ‘Php::Value::Value(const std::map<std::basic_string<char>, T>&) [with T = std::map<double, std::map<double, std::map<double, std::map<std::basic_string<char>, std::map<int, double> > > > >]’:
main.cpp:428:9: required from here
/usr/include/phpcpp/value.h:113:34: error: no matching function for call to ‘Php::Value::setRaw(const char*, std::basic_string<char>::size_type, const std::map<double, std::map<double, std::map<double, std::map<std::basic_string<char>, std::map<int, double> > > > >&)’
for (auto &iter : value) setRaw(iter.first.c_str(), iter.first.size(), iter.second);
^~~~~~
In file included from /usr/include/phpcpp.h:42:0,
from main.cpp:1:
/usr/include/phpcpp/value.h:1165:10: note: candidate: void Php::Value::setRaw(int, const Php::Value&)
void setRaw(int index, const Value &value);
^~~~~~
/usr/include/phpcpp/value.h:1165:10: note: candidate expects 2 arguments, 3 provided
/usr/include/phpcpp/value.h:1176:10: note: candidate: void Php::Value::setRaw(const char*, int, const Php::Value&)
void setRaw(const char *key, int size, const Value &value);
^~~~~~
/usr/include/phpcpp/value.h:1176:10: note: no known conversion for argument 3 from ‘const std::map<double, std::map<double, std::map<double, std::map<std::basic_string<char>, std::map<int, double> > > > >’ to ‘const Php::Value&’
In file included from /usr/include/phpcpp.h:42:0,
from main.cpp:1:
/usr/include/phpcpp/value.h: In instantiation of ‘std::vector<T> Php::Value::vectorValue() const [with T = Curve]’:
/usr/include/phpcpp/value.h:723:30: required from ‘Php::Value::operator std::vector<T>() const [with T = Curve]’
main.cpp:414:33: required from here
/usr/include/phpcpp/value.h:483:13: error: no matching function for call to ‘std::vector<Curve>::push_back(Php::Value)’
result.push_back(get(i));
^~~~~~
In file included from /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/vector:64:0,
from /usr/include/phpcpp.h:19,
from main.cpp:1:
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/stl_vector.h:914:7: note: candidate: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Curve; _Alloc = std::allocator<Curve>; std::vector<_Tp, _Alloc>::value_type = Curve]
push_back(const value_type& __x)
^~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/stl_vector.h:914:7: note: no known conversion for argument 1 from ‘Php::Value’ to ‘const value_type& {aka const Curve&}’
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/stl_vector.h:932:7: note: candidate: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = Curve; _Alloc = std::allocator<Curve>; std::vector<_Tp, _Alloc>::value_type = Curve]
push_back(value_type&& __x)
^~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/stl_vector.h:932:7: note: no known conversion for argument 1 from ‘Php::Value’ to ‘std::vector<Curve>::value_type&& {aka Curve&&}’
make: *** [main.o] Error 1
Any suggestions how to fix these errors?
UPDATE
Have tried implementing an example Caleth suggested below by modifying C++ :
class Curve : public Php::Base
{
public :
string type;
double shape = 0.0;
double peak = 0.0;
double tpeak = 0.0;
double lag = 0.0;
string start;
double interval = 0.0;
int month_no = 0;
string month;
string start_date;
/**
* C++ constructor and destructor
*/
//Curve() {}
//virtual ~Curve() {}
Curve(Php::Value value) :
type(value["type"]),
shape(value["shape"]),
peak(value["peak"]),
tpeak(value["tpeak"]),
lag(value["lag"]),
interval(value["interval"]),
month_no(value["month_no"]),
month(value["month"]),
start_date(value["start_date"])
{}
operator Php::Value() const
{
Php::Value value;
value["type"] = type;
value["shape"] = shape;
value["peak"] = peak;
value["tpeak"] = tpeak;
value["lag"] = lag;
value["interval"] = interval;
value["month_no"] = month_no;
value["month"] = month;
value["start_date"] = start_date;
return value;
}
};
Php::Value get_all_curve_rates(Php::Parameters &params) {
vector<Php::Value> curves = params[0];
Php::Value data;
for (auto &c : curves) // access by reference to avoid copying
{
Curve curv = c;
if (curv.type == "t1")
data[curv.type][curv.peak][curv.tpeak][curv.lag][curv.start_date][curv.month_no] = 2.0;//get_curve_rate(curv.type, curv.shape, curv.peak, curv.tpeak, curv.lag, curv.start, curv.month, curv.interval);
else if (curv.type == "t2")
data[curv.type][curv.shape][curv.peak][curv.tpeak][curv.start_date][curv.month_no] = 1.0;//get_curve_rate(curv.type, curv.shape, curv.peak, curv.tpeak, curv.lag, curv.start, curv.month, curv.interval);
}
return data;
}
/**
* Switch to C context, because the Zend engine expects get get_module()
* to have a C style function signature
*/
extern "C" {
/**
* Startup function that is automatically called by the Zend engine
* when PHP starts, and that should return the extension details
* #return void*
*/
PHPCPP_EXPORT void *get_module()
{
// the extension object
static Php::Extension extension("test", "1.0");
// add functions so that they can be called from PHP scripts
// description of the class so that PHP knows which methods are accessible
Php::Class<Curve> curve("Curve");
extension.add("get_all_curve_rates", get_all_curve_rates, {
Php::ByVal("Curve", Php::Type::Array),
});
// return the extension details
return extension;
}
}
However now there are other error:
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3010:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:2975:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const basic_string& __str);
^~~~~~~~~~~~
main.cpp:417:33: error: call of overloaded ‘basic_string(Php::HashMember<std::basic_string<char> >)’ is ambiguous
start_date(value["start_date"])
^
In file included from /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/string:52:0,
from /usr/include/phpcpp.h:17,
from main.cpp:1:
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3027:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(basic_string&& __str)
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3010:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:2975:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const basic_string& __str);
^~~~~~~~~~~~
main.cpp:417:33: error: call of overloaded ‘basic_string(Php::HashMember<std::basic_string<char> >)’ is ambiguous
start_date(value["start_date"])
^
In file included from /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/string:52:0,
from /usr/include/phpcpp.h:17,
from main.cpp:1:
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3027:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(basic_string&& __str)
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3010:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:2975:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const basic_string& __str);
^~~~~~~~~~~~
make: *** [main.o] Error 1
You need to provide a way of converting Php::Values into Curves. Looking at the docs, this is generally done in class.
class Curve : public Php::Base
{
public :
string type;
double shape = 0.0;
double peak = 0.0;
double tpeak = 0.0;
double lag = 0.0;
string start;
double interval = 0.0;
int month_no = 0;
string month;
string start_date;
Curve(Php::Value value)
: type(value["type"]),
shape(value["shape"]),
// etc...
{}
operator Php::Value() const
{
Php::Value value;
value["type"] = type;
value["shape"] = shape;
// etc...
return value;
}
}

String::copy error

I have the following code and get the error later described how do i correct this?
The objective behind is to parse the following sentence into variables :
temp1+temp2=10
Code:
int main()
{
string line,var1;
int limit,len;
//some code here
// parse function declarartion :string parse(string ,char ,int &)
f1>>line;
len=line.length();
var1=parse(line,'+',limit);
line.copy(line,len-limit,limit);
//some code here
}
Error:
alice.cpp: In function ‘int main()’:
alice.cpp:65:40: error: no matching function for call to ‘std::basic_string<char>::copy(std::string&, int, int&)’
alicebob.cpp:65:40: note: candidate is:
/usr/include/c++/4.6/bits/basic_string.tcc:724:5: note: std::basic_string<_CharT, _Traits, _Alloc>::size_type std::basic_string<_CharT, _Traits, _Alloc>::copy(_CharT*, std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc>::size_type = unsigned int]
/usr/include/c++/4.6/bits/basic_string.tcc:724:5: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘char*’
If you just want to copy a substring into another string, why don't you use substr() instead?
int main()
{
std::string line("ceva5");
std::string var1;
int limit = 1,len;
//some code here
// parse function declarartion :string parse(string ,char ,int &)
// f1>>line;
len=line.length();
//
// var1=parse(line,'+',limit);
line = line.substr(limit, len-limit);
//some code here
std::cout << line << std::endl;
}
This should do what you want.
EDIT: I have not implemented your function but changed the code to work as string's copy().
Here is the explain: http://www.cplusplus.com/reference/string/string/copy/ ,The first arg is char*, So,Accroding to your question,I think your code should be
line.copy((char *)line.c_str(),len-limit,limit); // wrong code, lost the const
but this code is dangerous,Because std::copy()'s first arg is an array of characters to store the string 's substring, So,I think you code has something wrong.
Here is simple code:
std::string test1 = "test1";
char buffer[10] = {0};
test1.copy(buffer,2,3);
std::cout << "buffer is: " << buffer << std::endl;
and the output is :"buffer is: t1".

Why does istream_iterator<string>(ifstream("test.txt")) cause an error?

I have tried to write a code to read strings from file named "test.txt" and write the strings to standard output. The code below works well:
int main()
{
using namespace std;
ifstream file("test.txt");
copy(istream_iterator<string>(file),
istream_iterator<string>(),
ostream_iterator<string>(cout, " "));
}
However, with this modification, the code no longer compiles:
int main()
{
using namespace std;
copy(istream_iterator<string>(ifstream("test.txt")), // <-- Error here
istream_iterator<string>(),
ostream_iterator<string>(cout, " "));
}
Why doesn't this version compile?
The compiler I used is g++4.6.2, and the error as below:
ex11-16.cpp:16:65: error: no matching function for call to 'std::istream_iterator<std::basic_string<char> >::istream_iterator(std::ifstream)'
ex11-16.cpp:16:65: note: candidates are:
.../bits/stream_iterator.h:72:7: note: std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator(const std::istream_iterator<_Tp, _CharT, _Traits, _Dist>&) [with _Tp = std::basic_string<char>, _CharT = char, _Traits = std::char_traits<char>, _Dist = int, std::istream_iterator<_Tp, _CharT, _Traits, _Dist> = std::istream_iterator<std::basic_string<char> >]
.../bits/stream_iterator.h:72:7: note: no known conversion for argument 1 from 'std::ifstream {aka std::basic_ifstream<char>}' to 'const std::istream_iterator<std::basic_string<char> >&'
.../bits/stream_iterator.h:68:7: note: std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator(std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type&) [with _Tp = std::basic_string<char>, _CharT = char, _Traits = std::char_traits<char>, _Dist = int, std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type = std::basic_istream<char>]
.../bits/stream_iterator.h:68:7: note: no known conversion for argument 1 from 'std::ifstream {aka std::basic_ifstream<char>}' to 'std::istream_iterator<std::basic_string<char> >::istream_type& {aka std::basic_istream<char>&}'
.../bits/stream_iterator.h:64:26: note: std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator() [with _Tp = std::basic_string<char>, _CharT = char, _Traits = std::char_traits<char>, _Dist = int]
.../bits/stream_iterator.h:64:26: note: candidate expects 0 arguments, 1 provided
There are (I believe) two errors here:
(1) You need to put quotations around test.txt:
istream_iterator<string>(ifstream("test.txt"), ... );
(2) istream_iterator's constructor takes in an istream& (that is, an lvalue reference to a stream). Consequently, the stream that you pass in has to be an lvalue. However, passing in ifstream("test.txt") passes in a temporary object of type ifstream, which is an rvalue rather than an lvalue. This is the same reason that you can't do this:
int function(int& x) {
x++;
}
int main() {
function(137); // Error - 137 is an rvalue, but lvalue is needed.
}
Hope this helps!

Invalid conversion from 'char' to 'const char*'

I have a program that generates a single random character, using the randomCharacter function, and random strings, using the randomString function. The latter utilises the former, and breedWithMutation uses randomCharacter to probabilistically mutate a representation of a gene sequence.
#include <ctime>
#include <boost/random.hpp>
typedef boost::mt19937 randAlgorithm;
int mutationsPerGeneration = 100;
double probabilityOfMutation = 0.05;
string potentialAlleles = "abcdefghijklmnopqrstuvwxyz ";
size_t numberOfAlleles = potentialAlleles.size();
double random01(randAlgorithm & engine)
{
boost::uniform_real<double> u01;
return u01(engine);
}
int randomInteger(randAlgorithm & engine, size_t min, size_t max) {
boost::uniform_int<> minmax(min, max);
return minmax(engine);
}
string randomCharacter(randAlgorithm & engine, string charSet, size_t charSetSize) {
return charSet[randomInteger(engine, 0, charSetSize)];
}
string randomString(randAlgorithm & engine, size_t length, string charSet, size_t charSetSize) {
string s;
s.reserve(length);
for (int i = 0; i < length; i++) {
s.append(randomCharacter(engine, charSet, charSetSize));
}
return s;
}
string breedWithMutation(randAlgorithm & engine, string originalGenome, size_t genomeSize) {
string mutatedGenome;
mutatedGenome.reserve(genomeSize);
double mutationDraw;
for (size_t i = 0; i < genomeSize; i++) {
mutationDraw = random01(engine);
if (mutationDraw < probabilityOfMutation) { //The allele undergoes mutation
mutatedGenome.append(randomCharacter(engine, potentialAlleles, numberOfAlleles));
}
else {
mutatedGenome.append(originalGenome[i]);
}
}
return mutatedGenome;
}
However, when I build the application, I get these errors:
main.cpp: In function ‘std::string randomCharacter(randAlgorithm&, std::string, size_t)’:
main.cpp:31:55: error: invalid conversion from ‘char’ to ‘const char*’
main.cpp:31:55: error: initializing argument 1 of ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]’
main.cpp: In function ‘std::string breedWithMutation(randAlgorithm&, std::string, size_t)’:
main.cpp:53:45: error: invalid conversion from ‘char’ to ‘const char*’
main.cpp:53:45: error: initializing argument 1 of ‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::append(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>]’
The line numbers in the errors don't line up perfectly, I realise, but the first two errors refer to the only line in randomCharacter, and the third and fourth errors refer to this line: mutatedGenome.append(originalGenome[i]); in breedWithMutation. What is causing this error?
In C++, char and string are distinctly different types. One cannot implicitly convert a char value to a string (as you are trying to do in randomCharacter).
You could change the return type of randomCharacter to be char instead of string, though that may require changes elsewhere too (I haven't reviewed your code in detail).
Change the return type of randomCharacter() to char.
It's not an invalid conversion to const char, it's an invalid conversion to const char*. Strings in plain C are just arrays of characters, or const char*s. So, you're using a single character where you should be using a string.
To examine one instance: You've set up randomCharacter() to return a C++ string, but in actuality, you're trying to return a single character from charSet. It makes more sense to me for you to make the function return a char, but that's your decision to make.