Why does stackconst string not compile in g++?
The members of a standard container have to be copy assignable or movable (C++11). If the type is const
it fails the requirements.
Why does const prevent this from compiling?
A const_iterator
is an iterator that points to const value (like a const T* pointer); dereferencing it returns a reference to a constant value (const T&) and prevents modification of the referenced value: it enforces const-correctness.
When you have a const reference to the container, you can only get a const_iterator.
Change the iterator to const_iterator:
std::vector<double>::const_iterator it;
or use auto:
for (auto it = ds.begin(); it != ds.end(); it++) { // Compiler error. No suitable "="
dum = dum + std::to_string(*it) + " ";
}
or range based for loop:
for (auto a: ds)
dum = dum + std::to_string(a) + " ";
Same code compiling in g++, but not in VS
double x1[dim];
is a VLA (variable length array). It is not standard C++.
The reason why it works on gcc
is that gcc
has an extension which allows VLAs. VS2015 doesn't, so that's why it doesn't compile (it has its own set extensions though, just not that one).
The best alternative is a std::vector
:
std::vector<double> x1(dim); //array of size dim
If you can't use that, you can still use a manual dynamic array (although that is not recommended):
double* x1 = new double[dim];
delete[] x1; //Don't forget to delete it when you are done
//Alternatively, create a class which wraps the dynamic array, so you can use RAII
problem with constructors and g++ compile recipe
None of the solutions given above were correct.The problem was within my compilation recipe.These functions started existing after C++11 so if you're using something like that your compilation recipe should be:
g++ -g -std=c++11 -o executable file.cpp main.cpp
Why does not std:string + int give compilation error?
When your colleague only used integer literals, these will be converted to char
- You will however see a warning if the value of the integer is too big. The operator that gets called is
std::string operator+(const std::string &s, char c); // actually it's basic_string<> with some CharT...
Or the +=
variant ;)
On how to find all the calls. You could compile (w/o inlining) all the code, objdump
it, grep
for all the operator occurrences and use addr2line
on the filtered addresses:
$ cat string-plus.cpp
#include <string>
int main()
{
std::string a = "moof ";
a += 192371;
}
$ g++ -g string-plus.cpp
string-plus.cpp: In function ‘int main()’:
string-plus.cpp:5: warning: overflow in implicit constant conversion
$ objdump -Cd a.out | \
grep 'call.*std::string::operator+=(char)@plt' | \
tr -d ' ' | \
cut -d: -f1 | \
xargs addr2line -Cfe string-plus
main
??:0
This however hasn't given me the line number... At least the call site is there ;)
The -C
switch enables c++ name demangling. Which can also be done manually with binutls c++filt
.
Funnily enough, there is a definition of operator+
for string
and char
, but only when using operator+=
the integer literal is converted to char
, I have to pass a char
literal (or value) for operator+
to be used.
To find the mangled name of your operator:
$ cat a.cpp
#include <string>
int main()
{
std::string a = "moof ";
a = a + char(1);
}
$ g++ a.cpp
$ objdump -t a.out | c++filt | grep operator+ | cut -d ' ' -f1
08048780
$ objdump -t a.out | grep 0804878
08048780 w F .text 00000067 _ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S3_
The last one is the name you are searching for - which can be used to grep w/o name demangling.
I really don't know a better way to do this... :/
Why do compilers allow string literals not to be const?
The C standard does not forbid the modification of string literals. It just says that the behaviour is undefined if the attempt is made. According to the C99 rationale, there were people in the committee who wanted string literals to be modifiable, so the standard does not explicitly forbid it.
Note that the situation is different in C++. In C++, string literals are arrays of const char. However, C++ allows conversions from const char * to char *. That feature has been deprecated, though.
g++ error in compiling while using std::string[5] as a type in std::map
g++ error in compiling while using std::string[5] as a type in std::map<>
Arrays cannot be stored as elements of std::map
. You can store classes though, and arrays can be members of a class. The standard library provides a template for such array wrapper. It's called std::array
. You can use that as the element of the map instead.
Sidenote: std::map
isn't the only standard container with such limitation. std::array
is the only standard container that can itself contain arrays as elements.
Related Topics
Why Array Index Start from '0'
How Is If Statement Evaluated in C++
Is Clrscr(); a Function in C++
Constexpr Not Working If the Function Is Declared Inside Class Scope
Is It Illegal to Invoke a Std::Function<Void(Args...)> Under the Standard
Factory Method Implementation - C++
How to Implement "_Mm_Storeu_Epi64" Without Aliasing Problems
How to Write Make_Unique() in VS2012
C++ Template Function Default Value
Cmake Imported Library Behaviour
Why There Is No Std::Copy_If Algorithm
Opencv's Canny Edge Detection in C++
How to Parse Mustache with Boost.Xpressive Correctly
What Is Default Storage Class for Global Variables