compilation error while using swap method for queue in C++ - c++

I have error: ‘class std::queue<int>’ has no member named ‘swap’ while compiling following code
#include <iostream> // std::cout
#include <queue> // std::queue
int main ()
{
std::queue<int> foo,bar;
foo.push (10); foo.push(20); foo.push(30);
bar.push (111); bar.push(222);
foo.swap(bar);
std::cout << "size of foo: " << foo.size() << '\n';
std::cout << "size of bar: " << bar.size() << '\n';
return 0;
}
I'm using g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 for compiling this code,can anyone have a idea for this error?

Use:
std::swap(foo, bar);
It appear that since c++11, you have std::queue::swap
http://www.cplusplus.com/reference/queue/queue/swap-free/
g++ 4.6 appears to not accept -std=c++11, so you must upgrade your compiler for this method to work.
[edit]
g++ 4.6 accepts -std=c++0x to enable c++11

Related

Why MacOS clang can't use C++17 std?

I want to use c++1z in MacOS10.14.4, like this g++ -std=c++1z test.cpp -o test. But the clang can't compile the code.
The error as follows.
In file included from test.cpp:3:
/Library/Developer/CommandLineTools/usr/include/c++/v1/any:599:5: error: static_assert failed due to requirement 'is_constructible<basic_string<char> &&, _RawValueType
&>::value' "ValueType is required to be an lvalue reference or a CopyConstructible type"
static_assert(is_constructible<_ValueType, _RawValueType &>::value,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:29:19: note: in instantiation of function template specialization 'std::__1::any_cast<std::__1::basic_string<char> &&>' requested here
auto b = std::any_cast<std::string&&>(a); //< rvalue reference (no need for std::move)
^
1 error generated.
But the same code can work on Linux. The code as follows.
#include <string>
#include <iostream>
#include <any>
int main()
{
// simple example
auto a = std::any(12);
std::cout << std::any_cast<int>(a) << '\n';
try {
std::cout << std::any_cast<std::string>(a) << '\n';
}
catch(const std::bad_any_cast& e) {
std::cout << e.what() << '\n';
}
// advanced example
a = std::string("hello");
auto& ra = std::any_cast<std::string&>(a); //< reference
ra[1] = 'o';
std::cout << "a: " << std::any_cast<const std::string&>(a) << '\n'; //< const reference
auto b = std::any_cast<std::string&&>(a); //< rvalue reference (no need for std::move)
// Note, 'b' is a move-constructed std::string, 'a' is now empty
std::cout << "a: " << *std::any_cast<std::string>(&a) //< pointer
<< "b: " << b << '\n';
}
clang version: Apple LLVM version 10.0.1 (clang-1001.0.46.4)
And I use the gcc to compile this code, but didn't work either.
This seems to be from https://developercommunity.visualstudio.com/content/problem/200281/stdany-cast-static-assert-error-because-of-is-cons.html, which has an answer from Microsoft. The answer there was that this was a defect LWG 2768, so the fix may not have been implemented in older implementations of the standard library. For example, this compiles in clang 6.0.0 and gcc 7.4, but not clang 7.0.0 and gcc 8.1.
The reason is that you can't take an rvalue reference of an lvalue any. Fix this by either taking an lvalue reference and moving that or taking an rvalue reference of a moved any:
std::move(std::any_cast<std::string&>(a));
std::any_cast<std::string&&>(std::move(a));

auto template parameters: g++ 7.3 vs clang++ 6.0 : Which compiler is correct?

Two compilers produce different results for this code example.
Clang generates two different types. G++ uses same type for fu and fi.
Which one is standard compliant?
#include <iostream>
template< auto IVAL>
struct foo {
decltype(IVAL) x = -IVAL;
};
int main()
{
foo<10u> fu;
foo<10> fi;
std::cout << fi.x << " " << fu.x << '\n';
return 0;
}
g++-7.3 output:
4294967286 4294967286
clang-6.0 output:
-10 4294967286
gcc is wrong here, these are clearly two distinct types.
And to confirm - this bug is fixed in gcc 8.0.1
Sample code

move-assigning a std::map with an aligned value type segfaults

The following code segfaults consistently for me on clang 3.8 but succeeds on clang 3.7. I compile with clang++ -std=c++14 -O2 test_case.cpp -o test_case in both cases. If I compile with optimisations off on clang 3.8 the program runs to completion.
I'm guessing that the compiler is taking some liberties when optimising - my question is: Is the compiler allowed to optimise in this way, or have I found my first compiler bug?
#include <iostream>
#include <map>
struct __attribute__((aligned(16))) troublesome {
float s;
};
int main() {
std::map<int, troublesome> m{{0, troublesome{}}};
std::map<int, troublesome> n{{1, troublesome{}}};
std::cout << "GOT HERE" << std::endl; // always prints
m = std::move(n); // segfault happens here
std::cout << "GOT HERE TOO" << std::endl; // only get here on old clang
}

Is this (auto && elem : v) syntax simple C++? what compiler should I use to have it compile?

I used to code in C++ 12 years ago, but left it for other simpler languages due to my job.
I'd like to renew my knowledge and tried to compile the solution proposed here, just to try this new way to iterate on vectors. But ran into a compile error:
expected initializer before ‘:’ token
I didn't know it was possible to avoid explicit declaration of iterators like that in C++ with the use of this (auto && elem : v). What version of C++ is it?
b.cpp
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <string>
#include <set>
int main()
{
std::vector<std::pair<std::string, std::string>> v
{ {"handgun", "bullets"},
{"turret", "bullets"}};
std::cout << "Initially: " << std::endl << std::endl;
for (auto && elem : v)
std::cout << elem.first << " " << elem.second << std::endl;
return 0;
}
Compilation
$ cc b.cpp -std=c++0x -o myprog
Errors
b.cpp: In function ‘int main()’:
b.cpp:15: error: expected initializer before ‘:’ token
...
C++ Compilers I use: g++
$ g++ --version
gives
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)
Copyright (C) 2010 Free Software Foundation, Inc.
Your compiler is too old. Ranged-based for loops weren't added until 4.6.
Also, ignore the comments. cc is usually symlinked to gcc. From the manual:
GCC recognizes files with these names and compiles them as C++
programs even if you call the compiler the same way as for compiling C
programs (usually with the name gcc).
Following pupper's advice, I adapted my code to the below:
#include <iostream>
#include <vector>
int main()
{
std::vector<std::pair<std::string, std::string>> v
{ {"handgun", "bullets"},
{"turret", "bullets"}};
std::cout << "started: " << std::endl;
std::vector<std::pair<std::string, std::string>>::iterator Current_Iterator = v.begin();
while(Current_Iterator != v.end())
{
std::cout << Current_Iterator->first << " " << Current_Iterator->second << std::endl;
Current_Iterator++;
}
return 0;
}
It still doesn't compile with the gcc on my system, giving
b.cpp:(.text+0x134): undefined reference to ``std::cout'
...
But it works with g++:
$ g++ b.cpp -std=c++0x -o myprog && ./myprog
started:
handgun bullets
turret bullets

std::underlying_type support in clang++

I assume C++ Compound type alterations support should be enabled in clang++ by -std=c++11 switch. But I'm unable to compile this code using clang:
#include <iostream>
#include <type_traits>
enum class A {a,b,c};
enum B : short {x,y,z};
int main() {
typedef std::underlying_type<A>::type A_under; // int
typedef std::underlying_type<B>::type B_under; // short
std::cout << std::boolalpha;
std::cout << "typedefs of int:" << std::endl;
std::cout << "A_under: " << std::is_same<int,A_under>::value << std::endl;
std::cout << "B_under: " << std::is_same<int,B_under>::value << std::endl;
return 0;
}
I get this error:
$ clang++ underlyingtype.cpp -std=c++11
underlyingtype.cpp:10:16: error: no type named 'underlying_type' in namespace 'std'
typedef std::underlying_type<A>::type A_under; // int
Any idea why this is happening?
Further information:
lashgar#fengdu:~/code$ clang++ --version
clang version 3.8.0 (http://llvm.org/git/clang.git 1ad799453a2e54cfded555a03fd58dbd102c5f62) (http://llvm.org/git/llvm.git af5ff60200812e518c72a022fb4c66b9a5f0116a)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/lashgar/opt/llvm/bin
Here's a link to an online compiler with libstdc++ 4.6.4 that reproduces this error.
Just make sure to get the version of your Standard Library. libstdc++ 4.7 and higher or libc++ 3.0 and higher should work correctly.