Taking decltype of main - c++11

Trying to invoke hi or std::move on it results in this:
/tmp/cch3DRvH.o: In function `main':
main.cpp:(.text.startup+0x5): undefined reference to `hi(int, char**)'
collect2: error: ld returned 1 exit status
#include <type_traits>
#include <utility>
#include <iostream>
#include <typeinfo>
#include <functional>
int main(int argc, char* argv[])
{
decltype(main) hi;
decltype(main) hi2;
// std::function<int(int, char**)> hi2 = std::move(hi);
// hi(argc, argv);
std::cout << std::boolalpha;
std::cout << std::is_same<decltype(main), decltype(hi)>::value << std::endl;
std::cout << std::is_function<decltype(main)>::value << std::endl;
std::cout << std::is_function<decltype(hi)>::value << std::endl;
std::cout << std::is_same<decltype(std::move(main)), decltype(std::move(hi))>::value << std::endl;
std::cout << std::is_same<decltype(hi2), decltype(hi)>::value << std::endl;
return 0;
}
Output:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:16:54: warning: ISO C++ forbids taking address of function ‘::main’ [-Wpedantic]
std::cout << std::is_same<decltype(std::move(main)), decltype(std::move(hi))>::value << std::endl;
main.cpp:16:54: warning: ISO C++ forbids taking address of function ‘::main’ [-Wpedantic]
true
true
true
true
true
It seems hi is almost the same as main except it doesn't give warnings like when using std::cout << hi. Is it possible to get this program to not output undefined reference tohi(int, char**)'`?

decltype(main) is an alias for the type int(int, char **). You have declared a function hi with this type but did not define it.
To get rid of the undefined reference error, just define the function:
int hi( int, char ** ) {
return 0;
}
The messages that appear before true are not output from your program but from the compiler.

Related

Selecting which overload is used in c++11

In the following code, as none of the arguments is const, i can't understand why the second overload is called in the 3 following cases.
#include <iostream>
#include <algorithm>
using namespace std;
void ToLower( std::string& ioValue )
{
std::transform( ioValue.begin(), ioValue.end(), ioValue.begin(), ::tolower );
}
std::string ToLower( const std::string& ioValue )
{
std::string aValue = ioValue;
ToLower(aValue);
return aValue;
}
int main()
{
string test = "test";
cout<<"Hello World" << endl;
// case 1
cout << ToLower("test") << endl;
// case 2
cout << ToLower(static_cast<string>(test)) << endl;
// case 3
cout << ToLower(string(test)) << endl;
}
In all 3 cases you are creating a temporary std::string, this is an unnamed object, an R-value. R-values aren't allowed to bind to non-const l-value references (T&) and so only the overload taking const std::string& ioValue is valid.
The reasoning is the return type is std::string for the second function but void for the first. std::cout << (void) << std::endl is not a valid set of operations. std::cout << (std::string) << std::endl is. If you return a std::string& from the first function you'd probably see #2 & #3 probably use your first function call.

How to correctly transfer the ownership of a shared_ptr?

I have the following code snipet:
// code snipet one:
#include <memory>
#include <iostream>
#include <queue>
struct A {
uint32_t val0 = 0xff;
~A() {
std::cout << "item gets freed" << std::endl;
}
};
typedef std::shared_ptr<A> A_PTR;
int main()
{
std::queue<A_PTR> Q;
Q.push(std::make_shared<A>());
auto && temp_PTR = Q.front();
std::cout << "first use count = " << temp_PTR.use_count() << std::endl;
Q.pop();
std::cout << "second use count = " << temp_PTR.use_count() <<std::endl;
return 0;
}
After running it, I got the result as following:
first use count = 1
item gets freed
second use count = 0
Q1: is anybody can explain what the type of temp_PTR after the third line of main function is called?
if I change that line as
A_PTR && temp_PTR = Q.front();
compiler complains that
main.cpp: In function 'int main()':
main.cpp:26:32: error: cannot bind '__gnu_cxx::__alloc_traits > >::value_type {aka std::shared_ptr}' lvalue to 'A_PTR&& {aka std::shared_ptr&&}'
A_PTR && temp_PTR = Q.front();
Q2: I remember that the return value of a function should be a r-value, but it seems here the compiler tell me: " hey, the return value of Queue.front() is a l-value", why is here?
For Q2, I just check the C++ docs, that the return value of Queue.front() is refernece, that means it return a l-value
reference& front();
const_reference& front() const;
For Q3, it works for A_PTR temp_PTR = std::move(Q.front());, it is what I want.

serialize temporary into boost archive

The following is not possible for any boost output archive:
int foo(){
return 4;
}
ar << static_cast<unsigned int>(foo());
Is there an alternative without out creating a local temporary x=foo().
and why is the underlying archive operator <<(T & t) not const reference , for an output archive such that the above would work?
This seems to work, and I think this is why:
... To help detect such cases, output archive operators expect to be
passed const reference arguments.
It seems worth noting that in your example ar << foo(); does not work either (i.e. it doesn't have to do with your cast).
#include <fstream>
#include <iostream>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
unsigned int foo(){
return 4;
}
int main()
{
{
std::ofstream outputStream("someFile.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << static_cast<const int&>(foo());
}
std::ifstream inputStream("someFile.txt");
boost::archive::text_iarchive inputArchive(inputStream);
int readBack;
inputArchive >> readBack;
std::cout << "Read back: " << readBack << std::endl;
return 0;
}

C++ gettid() was not declared in this scope

A simple program is:
I would like to get the thread ID of both of the threads using this gettid function. I do not want to do the sysCall directly. I want to use this function.
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/date_time/date.hpp>
#include <unistd.h>
#include <sys/types.h>
using namespace boost;
using namespace std;
boost::thread thread_obj;
boost::thread thread_obj1;
void func(void)
{
char x;
cout << "enter y to interrupt" << endl;
cin >> x;
pid_t tid = gettid();
cout << "tid:" << tid << endl;
if (x == 'y') {
cout << "x = 'y'" << endl;
cout << "thread interrupt" << endl;
}
}
void real_main() {
cout << "real main thread" << endl;
pid_t tid = gettid();
cout << "tid:" << tid << endl;
boost::system_time const timeout = boost::get_system_time() + boost::posix_time::seconds(3);
try {
boost::this_thread::sleep(timeout);
}
catch (boost::thread_interrupted &) {
cout << "thread interrupted" << endl;
}
}
int main()
{
thread_obj1 = boost::thread(&func);
thread_obj = boost::thread(&real_main);
thread_obj.join();
}
It gives Error on compilation; The use of gettid() has been done according to the man page:
$g++ -std=c++11 -o Intrpt Interrupt.cpp -lboost_system -lboost_thread
Interrupt.cpp: In function ‘void func()’:
Interrupt.cpp:17:25: error: ‘gettid’ was not declared in this scope
pid_t tid = gettid();
This is a silly glibc bug. Work around it like this:
#include <unistd.h>
#include <sys/syscall.h>
#define gettid() syscall(SYS_gettid)
The man page you refer to can be read online here. It clearly states:
Note: There is no glibc wrapper for this system call; see NOTES.
and
NOTES
Glibc does not provide a wrapper for this system call; call it using syscall(2).
The thread ID returned by this call is not the same thing as a POSIX thread ID (i.e., the opaque value returned by pthread_self(3)).
So you can't. The only way to use this function is through the syscall.
But you probably shouldn't anyway. You can use pthread_self() (and compare using pthread_equal(t1, t2)) instead. It's possible that boost::thread has its own equivalent too.
Additional to the solution provided by Glenn Maynard it might be appropriate to check the glibc version and only if it is lower than 2.30 define the suggested macro for gettid().
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
#include <sys/syscall.h>
#define gettid() syscall(SYS_gettid)
#endif

Move or swap a stringstream

I want to move a stringstream, in the real world application I have some stringstream class data member, which I want to reuse for different string's during operation.
stringstream does not have a copy-assignment or copy constructor, which makes sense. However, according to cppreference.com and cplusplus.com std::stringstream should have a move assignment and swap operation defined. I tried both, and both fail.
Move assignment
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
int main () {
std::stringstream stream("1234");
//stream = std::move(std::stringstream("5678"));
stream.operator=(std::move(std::stringstream("5678")));
//stream.operator=(std::stringstream("5678"));
return 0;
}
source: http://ideone.com/Izyanb
prog.cpp:11:56: error: use of deleted function ‘std::basic_stringstream<char>& std::basic_stringstream<char>::operator=(const std::basic_stringstream<char>&)’
stream.operator=(std::move(std::stringstream("5678")));
The compiler states that there is no copy assignment for all three statements, which is true. However, I fail to see why it is not using the move-assignment, especially since std::move is supposed to return a rvalue reference. Stringstream should have a move assignment, as shown here: http://en.cppreference.com/w/cpp/io/basic_stringstream/operator%3D
PS: I'm working with c++11, hence rvalue-references are part of the 'world'.
Swap
This I found really strange, I copied example code from cplusplus.com and it failed:
// swapping stringstream objects
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
int main () {
std::stringstream foo;
std::stringstream bar;
foo << 100;
bar << 200;
foo.swap(bar);
int val;
foo >> val; std::cout << "foo: " << val << '\n';
bar >> val; std::cout << "bar: " << val << '\n';
return 0;
}
source: http://ideone.com/NI0xMS
cplusplus.com source: http://www.cplusplus.com/reference/sstream/stringstream/swap/
prog.cpp: In function ‘int main()’:
prog.cpp:14:7: error: ‘std::stringstream’ has no member named ‘swap’
foo.swap(bar);
What am I missing? Why can't I move or swap a stringstream? How should I swap or move a stringstream?
This is a missing feature on GCC : see bug 54316 , it has been fixed (you can thank Jonathan Wakely) for the next versions (gcc 5)
Clang with libc++ compiles this code :
int main () {
std::stringstream stream("1234");
std::stringstream stream2 = std::move(std::stringstream("5678"));
return 0;
}
Live demo
And it also compiles the example with std::stringstream::swap
I have an alternative to moving or swapping, one can also clear and set a stringstream to a new string:
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
int main () {
std::stringstream ss("1234");
ss.clear();
ss.str("5678");
int val;
ss >> val; std::cout << "val: " << val << '\n';
return 0;
}
It's a clean work around that does not require one to refactor code, except for the localized section where the swap is changed to a clear() and str().

Resources