ambiguous call to function template (reverse) - c++

This code compiles with GCC, but gives ambiguous call to overloaded function for MSVC:
https://godbolt.org/z/W89xn15d3
#include <string>
template <typename Iter>
void reverse(Iter begin, Iter end){
if (std::distance(begin, end) == 0)
return;
auto left = begin,
right = std::prev(end);
while (left < right)
std::swap(*left++, *right--);
}
std::string reverseWordsInString(std::string str) {
reverse(str.begin(), str.end()); // ambiguous call
// reverse(str.data(), str.data() + str.size());
size_t wordLength = 0;
for (size_t i = 0; i < str.size(); ++i)
{
if (str[i] != ' ')
{
++wordLength;
continue;
}
const size_t offset = i - wordLength;
reverse(str.data() + offset, str.data() + i);
wordLength = 0;
}
// reverse(std::prev(str.end(), wordLength), str.end()); // ambiguous
reverse(str.data() + str.size() - wordLength, str.data() + str.size());
return str;
}
MSVC output:
example.cpp
<source>(16): error C2668: 'reverse': ambiguous call to overloaded function
<source>(4): note: could be 'void reverse<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>>(Iter,Iter)'
with
[
_Elem=char,
Iter=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>
]
C:/data/msvc/14.33.31631/include\xutility(5619): note: or 'void std::reverse<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>>(const _BidIt,const _BidIt)' [found using argument-dependent lookup]
with
[
_Elem=char,
_BidIt=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>
]
<source>(16): note: while trying to match the argument list '(std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>, std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>)'
with
[
_Elem=char
]
Compiler returned: 2
Who is wrong and why?

You'll get the same error in GCC if you #include <algorithm>. MSVC is including <algorithm> implicitly when you #include <string>.
The portable solution is to either:
rename your function to something that doesn't exist in the standard library
be explicit about the namespace when you want to call your function:
::reverse(...);
place your function in a namespace of your own, and then prepend the call with that namespace.
myns::reverse(...);

Related

Check equality from a void pointer typecasted data

in my below program i get compilation error
error: comparison between distinct pointer types 'unsigned char*' and 'const char*' lacks a cast
How to tackle this and do comparison
#include <iostream>
#include <vector>
using namespace std;
std::vector<std::uint8_t> vec;
void Init(void* tmp)
{
auto dd = static_cast<std::uint8_t *>(tmp);
std::cout<<"loop : "<<dd<<std::endl;
if(dd == "BBBB_DDDDD_XXUSTYY_99_7DFFXX9B67")
std::cout<<"equal";
else
std::cout<<"not equal";
}
std::string PadIt(std::string& str, std::size_t outputLength)
{
if (outputLength > str.size()) {
char paddingChar = ' ';
str.insert(str.size(), outputLength - str.size(), paddingChar);
}
std::cout<<"PadIt str is : "<<str<<" size is: "<<str.size()<<std::endl;
return str;
}
int main() {
std::string key_str = "BBBB_DDDDD_XXUSTYY_99_7DFFXX9B67";
std::string obid = PadIt(key_str,16);
std::vector<std::uint8_t> vec(obid.begin(),obid.end());
Init(vec.data());
}
I want to do comparison of string in Init function, if a wrong string is given it show give false

Codewars: Solving Kata - Highest and Lowest C++

I was solving kata "Highest and Lowest" in codewars.com and got some issues while testing.
Here is my code:
#include <iostream>
#include <list>
#include <sstream>
#include <vector>
using namespace std;
vector<string> splitString(string str) {
stringstream ssin(str);
long countSpaces = count(str.begin(), str.end(), " ") + 1;
vector<string> numbers(countSpaces);
int i = 0;
while (ssin.good() && i < countSpaces + 1) {
ssin >> numbers[i];
++i;
}
return numbers;
}
string highAndLow(const string& numbers) {
int maxAndMin[] = { 0, 0 };
vector<string> stringNums = splitString(numbers);
int length = static_cast<int>(stringNums.size());
for (int i = 0; i < length; i++) {
int number = stoi(stringNums[i]);
if (number > maxAndMin[0]) maxAndMin[0] = number;
if (number < maxAndMin[1]) maxAndMin[1] = number;
}
string result;
stringstream ss;
ss << maxAndMin[0] << " " << maxAndMin[1];
result = ss.str();
return result;
}
And issues:
In file included from main.cpp:1:
In file included from /usr/local/include/igloo/igloo_alt.h:10:
In file included from /usr/local/include/igloo/igloo_framework.h:12:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ios:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/char_traits.h:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algobase.h:71:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/predefined_ops.h:241:17: error: comparison between pointer and integer ('char' and 'const char *')
{ return *__it == _M_value; }
~~~~~ ^ ~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:3188:6: note: in instantiation of function template specialization '__gnu_cxx::__ops::_Iter_equals_val<char const[2]>::operator()<__gnu_cxx::__normal_iterator<char *, std::__cxx11::basic_string<char> > >' requested here
if (__pred(__first))
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:4115:19: note: in instantiation of function template specialization 'std::__count_if<__gnu_cxx::__normal_iterator<char *, std::__cxx11::basic_string<char> >, __gnu_cxx::__ops::_Iter_equals_val<char const[2]> >' requested here
return std::__count_if(__first, __last,
^
./solution.cpp:10:24: note: in instantiation of function template specialization 'std::count<__gnu_cxx::__normal_iterator<char *, std::__cxx11::basic_string<char> >, char [2]>' requested here
long countSpaces = count(str.begin(), str.end(), " ") + 1;
^
1 error generated.
Could you explain me please, what's wrong here?
Try to understand the error message, it contains all relevant information:
First, what the compiler does not like:
error: comparison between pointer and integer ('char' and 'const char *')
And then, which part of your code causes the issue:
long countSpaces = count(str.begin(), str.end(), " ") + 1;
Deep inside that count function, there is a loop comparing every element of str to the " ", you figure out the rest.

I need help fixing a C++ white space detector

I need help fixing the following code, it is a c++ whitespace detector that uses different words to produce different outputs:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
using namespace std;
string Line;
string firstWord[99];
string secondWord[99];
int lineFunction(string line) {
string line[199];
for (int i = 0; i < line.length(); i++) {
while (isspace(line[i]) == false) {
firstWord += line[i];
}
secondWord += line[i];
}
}
int main() {
cin >> Line;
lineFunction(Line);
if (firstWord == "A") {
if (secondWord == "B") {
cout << "AB";
}
}
}
The expected result when I input A B (with a space) should be the letters AB (without a space, to test how it works) printed onto the screen, as a result of the if statements, but I am trying to make the output configurable. The errors that I receive when I try to run this are:
main.cpp: In function ‘int lineFunction(std::string)’:
main.cpp:12:20: error: declaration of ‘std::string line [199]’ shadows a parameter
string line[199];
^
main.cpp:13:30: error: request for member ‘length’ in ‘line’, which is of non-class type ‘std::string [199] {aka std::basic_string [199]}’
for (int i = 0; i < line.length(); i++) {
^~~~~~
main.cpp:14:31: error: no matching function for call to ‘isspace(std::string&)’
while (isspace(line[i]) == false) {
^
In file included from /usr/include/c++/6/cctype:42:0,
from main.cpp:2:
/usr/include/ctype.h:118:1: note: candidate: int isspace(int)
__exctype (isspace);
^
/usr/include/ctype.h:118:1: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string}’ to ‘int’
In file included from /usr/include/c++/6/bits/basic_ios.h:37:0,
from /usr/include/c++/6/ios:44,
from /usr/include/c++/6/ostream:38,
from /usr/include/c++/6/iostream:39,
from main.cpp:3:
/usr/include/c++/6/bits/locale_facets.h:2565:5: note: candidate: template bool std::isspace(_CharT, const std::locale&)
isspace(_CharT __c, const locale& __loc)
^~~~~~~
/usr/include/c++/6/bits/locale_facets.h:2565:5: note: template argument deduction/substitution failed:
main.cpp:14:31: note: candidate expects 2 arguments, 1 provided
while (isspace(line[i]) == false) {
^
main.cpp:15:23: error: no match for ‘operator+=’ (operand types are ‘std::string [99] {aka std::basic_string [99]}’ and ‘std::string {aka std::basic_string}’)
firstWord += line[i];
~~~~~~~~~~^~~~~~~~~~
main.cpp:17:20: error: no match for ‘operator+=’ (operand types are ‘std::string [99] {aka std::basic_string [99]}’ and ‘std::string {aka std::basic_string}’)
secondWord += line[i];
~~~~~~~~~~~^~~~~~~~~~
main.cpp: In function ‘int main()’:
main.cpp:24:22: error: comparison between distinct pointer types ‘std::string* {aka std::basic_string*}’ and ‘const char*’ lacks a cast [-fpermissive]
if (firstWord == "A") {
^~~
main.cpp:25:27: error: comparison between distinct pointer types ‘std::string* {aka std::basic_string*}’ and ‘const char*’ lacks a cast [-fpermissive]
if (secondWord == "B") {
Here are some possible solutions to fix the errors.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
// don't use
// using namespace std;
// don't use global variables
// string Line;
// string firstWord[99]; you need strings, not arrays
// string secondWord[99];
// use references to return multiple values and no return value
// alternatively you could return a std::pair
void lineFunction(std::string line, std::string &firstWord, std::string &secondWord) {
// string line[199]; you don't need this variable
// line.length() return unsigned int so you should compare with unsigned int
// this whole loop makes no sense
// for (unsigned int i = 0; i < line.length(); i++) {
// this would result in a infinite loop
// while (isspace(line[i]) == false) {
// if (!std::isspace(line[i])) {
// firstWord += line[i];
// }
// secondWord += line[i];
// }
unsigned int i;
for (i = 0; i < line.length() && !std::isspace(line[i]); ++i) {
firstWord += line[i];
}
for (++i; i < line.length(); ++i) {
secondWord += line[i];
}
}
int main() {
std::string line;
// std::cin only reads until first whitespace
// std::cin >> line;
std::getline(std::cin, line);
std::string firstWord;
std::string secondWord;
lineFunction(line, firstWord, secondWord);
if (firstWord == "A" && secondWord == "B") {
std::cout << "AB";
}
}

‘pos’ was not declared in this scope

Getting this error currently:
main.cpp: In function ‘std::string class_name(const std::type_info&)’:
main.cpp:43:45: error: ‘pos’ was not declared in this scope
if (const size_t pos = name.find(prefix)); pos != string::npos)
I've been trying to mess around with this string but can't seem to get it to pass when I try to compile.
The code:
#include <string>
#include <map>
#include <array>
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <typeinfo>
using namespace std;
void horizontal_line(size_t n = 80)
{
cout << endl << string(n, '-');
}
void pause(size_t n = 80)
{
horizontal_line(n);
cout << "\n[Enter] to continue.";
cin.get();
}
string currency(const float& amount)
{
ostringstream ss;
ss.imbue(std::locale(""));
ss << showbase << put_money(amount * 100);
return ss.str();
}
string class_name(const type_info& typeinfo)
{
static const string prefix("class ");
static const size_t length = prefix.size();
string name(typeinfo.name ());
if (const size_t pos = name.find(prefix)); pos != string::npos)
name.erase(pos, length);
return name;
}
Trying to get it to compile to show the output for a vehicle list but having some trouble with this portion, the output obviously wont compile at the moment with this error. (Obviously this isn't the full code)
The syntax you are trying to use to declare AND initialize pos inside the if statement:
if (const size_t pos = name.find(prefix)); pos != string::npos)
Is valid only in C++17 and later. Also, you have an erroneous ) before the ; that you need to remove, the correct statement is:
if (const size_t pos = name.find(prefix); pos != string::npos)
For earlier versions of C++, you need to separate the declaration of pos from the if statement:
const size_t pos = name.find(prefix);
if (pos != string::npos)
Alternatively, you can perform the assignment of pos inside the if statement, just not the declaration, however the syntax is slightly different:
size_t pos;
if ((pos = name.find(prefix)) != string::npos)
If I understand your code correctly, this is probably what you meant to do:
size_t pos = name.find(prefix);
if(pos != string::npos)
name.erase(pos, length);
You’ve a semicolon directly after the if. So the 2nd time pos appears, it’s not in an if block which is the only place pos would be in scope.

How do I replace a single character like 'A' with something like "10"?

#include <iostream>
#include <string>
using namespace std;
int main ()
{
string s;
cin >> s;
for (int i = 0; i < s.size (); i++)
{
if (s[i] == 'A')
{
s[i] = "10";
}
cout << s[i];
}
return 0;
}
I am getting following error:
main.cpp: In function
'int main()': main.cpp:10:5: error: invalid conversion from 'const char*' to 'char' [-fpermissive] s[i]= "10";
Any help would be highly appreciated. Thank you.
You can find the position of A, starting from index 0 until end of the string and whenever you find, replace it with 10 using the information of both position where you found and the length of the string you would like to find in the given string.
Something like follows: https://www.ideone.com/dYvF8d
#include <iostream>
#include <string>
int main()
{
std::string str;
std::cin >> str;
std::string findA = "A";
std::string replaceWith = "10";
size_t pos = 0;
while ((pos = str.find(findA, pos)) != std::string::npos)
{
str.replace(pos, findA.length(), replaceWith);
pos += replaceWith.length();
}
std::cout << str << std::endl;
return 0;
}
why not use string::find() to locate the character you want to replace and then string::insert to insert a "10"? maybe not the best way, but can finish it correctly.
You code's question is that the operator[] of std::string returns a char&, and you can not assign a string literal to it.
And I think I should give you a function to implement it.
void Process(std::string& op)
{
auto pos=op.find('A');
op.erase(pos,1);
if(pos!=std::string::npos)
{
op.insert(pos,"10");
}
}