How to pass rvalue reference from caller to callee - c++11

Say I have code below
#include <iostream>
void foo(std::string && s) { std::cout << s; }
void bar(std::string && s) { foo(s); }
int main() {
bar("abc");
return 0;
}
I got compiling error:
error: cannot bind ‘std::string {aka std::basic_string}’ lvalue
to ‘std::string&& {aka std::basic_string&&}’ void
bar(std::string && s) { foo(s); }

Use std::move from <utility>:
#include <iostream>
#include <utility>
void foo(std::string && s) { std::cout << s; }
void bar(std::string && s) { foo(std::move(s)); }
int main() {
bar("abc");
return 0;
}
std::move is actually just a little bit of syntactical sugar, but is the common way of forwarding an rvalue reference.

Related

STD::FUNCTION C++

I'm still learning Modern C++ and I would like to clarify STD:FUNCTION,
Here is my sample code that works fine :
#include <iostream>
#include <functional>
using namespace std;
int func(function<bool()> foo) {
return 2;
}
struct fee {
bool operator()() {
return true;
}
};
int main() {
cout << func(fee());
}
It will display "2" on the console.
What I am wondering is why this does not work. I changed bool operator()() to bool operator()(int i).
#include <iostream>
#include <functional>
using namespace std;
int func(function<bool()> foo) {
return 2;
}
struct fee {
bool operator()(int i) {
return true;
}
};
int main() {
cout << func(fee());
}
The error says:
In function 'int main()':
18:20: error: could not convert 'fee()' from 'fee' to 'std::function<bool()>'
What should be the right thing to do ?
In the second example, the fee operator() function now takes an int as a parameter.
Therefore you need to change
int func(function<bool()> foo) {
return 2;
}
to
int func(function<bool(int)> foo) {
return 2;
}
to reflect that.

Error in storing outer class object in inner class C++

I was implementing the ring buffer and have encountered an error. What does it mean to store a reference of outer class(class ring) object(m_ring) in inner class(class iterator) and when I remove the reference(&) the program compiles correctly but crashes. Please explain what is happening.(See the comment in Ring.h) Sorry for bad English.
// Ring.h
#ifndef RING.H
#define RING.H
#include <iostream>
using namespace std;
template<class T>
class ring {
unsigned int m_size;
int m_pos;
T *m_values;
public:
class iterator;
public:
ring(unsigned int size) : m_size(size), m_pos(0)
{
m_values = new T[m_size];
}
~ring()
{
delete[] m_values;
}
void add(const T &val)
{
m_values[m_pos] = val;
m_pos++;
m_pos %= m_size;
}
T& get(int pos)
{
return m_values[pos];
}
iterator begin()
{
return iterator(0, *this);
}
iterator end()
{
return iterator(m_size, *this);
}
};
template<class T>
class ring<T>::iterator {
int m_pos;
ring &m_ring; // Removing & gives garbage output.
public:
iterator(int pos, ring& aRing) : m_pos(pos), m_ring(aRing){}
bool operator!=(const iterator &other) const
{
return other.m_pos != m_pos;
}
iterator &operator++(int)
{
m_pos++;
return *this;
}
iterator &operator++()
{
m_pos++;
return *this;
}
T &operator*()
{
// return m_ring.m_values[m_pos];
return m_ring.get(m_pos);
}
};
#endif // RING
Driver program :
// Ring_Buffer_Class.cpp
#include <iostream>
#include "ring.h"
using namespace std;
int main()
{
ring<string> textring(3);
textring.add("one");
textring.add("two");
textring.add("three");
textring.add("four");
// C++ 98
for(ring<string>::iterator it = textring.begin(); it != textring.end(); it++)
{
cout << *it << endl;
}
cout << endl;
// C++11
for(string value : textring)
{
cout << value << endl;
}
return 0;
}
I also observed that removing ~ring() (Destructor) results into correct output.
Expected output :
four
two
three
four
two
three

How can I use std::result_of to return the function type instead of void

I am trying to get the return type of a function that I bind in. In this instance I was expecting to see the return type of GetFactorialResult (int).
#include <iostream>
#include <boost/core/demangle.hpp>
#include <typeinfo>
namespace
{
const int testNumber = 10;
int GetFactorialResult(int number)
{
if (number > 1)
{
return number * GetFactorialResult(number - 1);
}
else
{
return 1;
}
}
template <typename Func, typename... Args>
void Submit(Func&& func, Args&&... args)
{
auto boundTask = std::bind(std::forward<Func>(func), std::forward<Args>(args)...);
using ResultType = typename std::result_of<decltype(boundTask)()>::type;
char const * name = typeid( ResultType ).name();
std::cout << boost::core::demangle( name ) << std::endl;
}
}
int main()
{
Submit([](int number)
{
GetFactorialResult(number);
}, number);
return 0;
}
Output
void
0
When I print the type of boundTask, I see what I expect:
std::_Bind<\main::{lambda(int)#1} (int)> (the backslash doesnt
exist, but couldnt figure out how to display it without it).
I assume I am getting void because of I'm doing decltype(boundTask)(), but if I remove the parenthesis, it fails to compile.
I only have access to c++11 features.

different behaviour for enums and all other types

Using gcc-4.8 with -std=c++11 I want to create a template function with one behaviour for enums and other behaviour for all other types. I try this
#include <type_traits>
#include <iostream>
template<class T, class = typename std::enable_if<std::is_enum<T>::value>::type>
void f(T& /*t*/)
{
std::cout << "enum" << std::endl;
}
template<class T, class = typename std::enable_if<!std::is_enum<T>::value>::type>
void f(T& /*t*/) {
std::cout << "not enum" << std::endl;
}
enum class E
{
A,
B
};
int main()
{
E e;
f(e);
return 0;
}
but compiler returns
1.cpp:11:6: error: redefinition of ‘template<class T, class> void f(T&)’
void f(T& /*t*/) {
^
1.cpp:5:6: error: ‘template<class T, class> void f(T&)’ previously declared here
void f(T& /*t*/)
^
I can comment out first template, it leads to compile error, and it's expectable.
And I also can comment out second template, in this case code code can be compiled.
What do I do wrong?
Because compiler sees them as the same function template, instead, you should do this:
#include <type_traits>
#include <iostream>
template<class T, typename std::enable_if<std::is_enum<T>::value, bool>::type = true>
void f(T& /*t*/)
{
std::cout << "enum" << std::endl;
}
template<class T, typename std::enable_if<!std::is_enum<T>::value, bool>::type = true>
void f(T& /*t*/) {
std::cout << "not enum" << std::endl;
}
enum class E
{
A,
B
};
int main()
{
E e;
f(e);
return 0;
}

boost::program_options overloaded validate is ambiguous

I am trying to parse a list input from the command line.
My class is derived from vector
The compiler complains about a overloaded validate being ambiguous.
I can see why, but do not know how to solve this issue.
Please help.
Below is a minimal example that generates the error. If the type of ch_list is changed to a vector, this minimal example compiles.
// g++ -std=c++11 -Wall -Wextra -pedantic test.cpp -o test -lboost_program_options -lboost_system
#include <vector>
#include <boost/program_options.hpp>
#include <iostream>
#include <vector>
using namespace std;
class mylist : public vector<int> {
public:
friend istream &operator>>(istream &is, mylist& l) {
int val;
is >> val;
l.push_back(val);
return is;
}
friend ostream& operator<<(ostream& os, const mylist& l) {
return os << l[0];
}
};
int main (int argc, char* argv[])
{
//vector<int> ch_list; // This works
mylist ch_list; // This doesn't
namespace po = boost::program_options;
po::options_description desc("Allowed options");
desc.add_options()
("ch", po::value<decltype(ch_list)>(&ch_list), "Set channel numbers")
;
po::variables_map vm;
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
}
catch (po::error& e) {
cerr << "ERROR: " << e.what() << "\n";
return EXIT_FAILURE;
}
if (!ch_list.empty())
cout << ch_list[0] << "\n";
return EXIT_SUCCESS;
}
I get these errors
/usr/include/boost/program_options/detail/value_semantic.hpp: In instantiation of ‘void boost::program_options::typed_value<T, charT>::xparse(boost::any&, const std::vector<std::basic_string<charT> >&) const [with T = mylist; charT = char]’:
test.cpp:47:5: required from here
/usr/include/boost/program_options/detail/value_semantic.hpp:169:13: error: call of overloaded ‘validate(boost::any&, const std::vector<std::basic_string<char> >&, mylist*, int)’ is ambiguous
/usr/include/boost/program_options/detail/value_semantic.hpp:169:13: note: candidates are:
/usr/include/boost/program_options/detail/value_semantic.hpp:81:10: note: void boost::program_options::validate(boost::any&, const std::vector<std::basic_string<charT> >&, T*, long int) [with T = mylist; charT = char]
/usr/include/boost/program_options/detail/value_semantic.hpp:129:10: note: void boost::program_options::validate(boost::any&, const std::vector<std::basic_string<charT> >&, std::vector<_RealType>*, int) [with T = int; charT = char]
You can use custom validator. Your code would be:
#include <vector>
#include <boost/program_options.hpp>
#include <iostream>
#include <vector>
using namespace std;
namespace po = boost::program_options;
class mylist : public vector<int> {
public:
};
void validate(boost::any& v,
const vector<string>& values,
mylist*, int) {
mylist dvalues;
for(vector<string>::const_iterator it = values.begin();
it != values.end();
++it) {
stringstream ss(*it);
copy(istream_iterator<int>(ss), istream_iterator<int>(),
back_inserter(dvalues));
if(!ss.eof()) {
throw ("Invalid coordinate specification");
}
}
v = mylist(dvalues);
}
int main (int argc, char* argv[])
{
//vector<int> ch_list; // This works
mylist ch_list; // This doesn't
po::options_description desc("Allowed options");
desc.add_options()
("ch", po::value< mylist >(&ch_list)->multitoken(), "Set channel numbers")
;
po::variables_map vm;
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
}
catch (po::error& e) {
cerr << "ERROR: " << e.what() << "\n";
return EXIT_FAILURE;
}
for (auto cc : ch_list)
cout << cc << endl;
return EXIT_SUCCESS;
}
Reference: boost::program_options config file option with multiple tokens

Resources