I'm trying to compile a simple program with GCC 7.2.1 on CentOS 7. After finding this package, I installed g++
with the following command on a fresh Docker CentOS image:
$ yum install centos-release-scl-rh
$ yum install devtoolset-7-gcc-c++
$ ln -s /opt/rh/devtoolset-7/root/usr/bin/g++ /usr/local/bin/g++
Confirming the install:
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-7/root/usr --mandir=/opt/rh/devtoolset-7/root/usr/share/man --infodir=/opt/rh/devtoolset-7/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --with-default-libstdcxx-abi=gcc4-compatible --with-isl=/builddir/build/BUILD/gcc-7.2.1-20170829/obj-x86_64-redhat-linux/isl-install --enable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 7.2.1 20170829 (Red Hat 7.2.1-1) (GCC)
Attempting to compile the program:
// main.cpp
#include <string>
#include <iterator>
#include <algorithm>
#include <iostream>
int main()
{
std::string foo {"hello world10m"};
foo.erase(std::find(std::cbegin(foo), std::cend(foo), '1'), std::cend(foo));
std::cout << foo << std::endl;
}
using the command:
$ g++ -std=gnu++14 -o test main.cpp
gives the following compiler error:
main.cpp: In function 'int main()':
main.cpp:9:79: error: no matching function for call to 'std::basic_string<char>::erase(__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>::const_iterator)'
foo.erase(std::find(std::cbegin(foo), std::cend(foo), '1'), std::cend(foo));
^
In file included from /opt/rh/devtoolset-7/root/usr/include/c++/7/string:52:0,
from main.cpp:1:
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4476:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
erase(size_type __pos = 0, size_type __n = npos)
^~~~~
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4476:7: note: no known conversion for argument 1 from '__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >' to 'std::basic_string<char>::size_type {aka long unsigned int}'
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4492:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::iterator std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::iterator) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; typename _Alloc::rebind<_CharT>::other::pointer = char*]
erase(iterator __position)
^~~~~
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4492:7: note: candidate expects 1 argument, 2 provided
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4512:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::iterator std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::iterator, std::basic_string<_CharT, _Traits, _Alloc>::iterator) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; typename _Alloc::rebind<_CharT>::other::pointer = char*]
erase(iterator __first, iterator __last);
^~~~~
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4512:7: note: no known conversion for argument 1 from '__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >' to 'std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}'
As far as I can tell, the wrong libstdc++
ABI is being selected. This example compiles fine on Ubuntu 16. What's going on?