Different between move and forward in this example - c++

The first example that take A by value does two moves and the one by refref only does one move. What is the difference?
struct A
{
A() { cout << "constructor" << endl;}
A(const A&) { cout << "copy constructor " << endl;}
void operator=(const A&) { cout << "assignment operator" << endl; }
A( A&&) { cout << "move copy constructor" << endl;}
void operator=(A&&) { cout << "move assignment operator" << endl;}
};
struct C {
void func(A t) {
d.a = std::move(t);
}
struct Data {
A a;
};
Data d;
};
struct B {
void func(A t) {
C c;
c.func(std::move(t));
}
};
//////////////////////////////////////////////////////////
struct C {
template<class T>
void func(T&& t) {
d.a = std::forward<T>(t);
}
struct Data {
A a;
};
Data d;
};
struct B {
template<class T>
void func(T&& t) {
C c;
c.func(std::forward<T>(t));
}
};

From cppreference.com:
When used according to the following recipe in a function template,
forwards the argument to another function exactly as it was passed to
the calling function.
template<typename T>
wrapper(T&& arg) {
foo(std::forward<T>(arg));
}
So in your snippet
struct B {
template<class T>
void func(T&& t) {
C c;
c.func(std::forward<T>(t));
}
};
The std::foward<T>(t) will simply forward your T&& object to c.func() exactly as B::func() was called. This doesn't require a move, which is why you are seeing fewer moves using std::forward<T>.
I would really recommend checking out Scott Meyer's blog post on this topic of std::move and std::forward: http://scottmeyers.blogspot.com/2012/11/on-superfluousness-of-stdmove.html

Related

C++ Variant visit overloaded function

I want to execute an overloaded function over a variant. The following code block works and compiles, but the visit invocation seems overly complex. Why can I not simply write:
std::visit(&f, something);
Working version and context:
#include <variant>
#include <string>
#include <iostream>
#include <functional>
struct A {
std::string name = "spencer";
};
struct B {
std::string type = "person";
};
struct C {
double age = 5;
};
void f(A a) {
std::cout << a.name << std::endl;
}
void f(B b) {
std::cout << b.type << std::endl;
}
void f(C c) {
std::cout << c.age << std::endl;
}
int main() {
std::variant<A, B, C> something{B{}};
std::visit([](auto&& x) {f(x);}, something);
}
Is there a simpler way?
std::visit(&f, something);
This is not valid, because f is not a single function. &f says "give me a pointer to f". But f isn't one thing; it's three functions which happen to share a name, with three separate pointers.
std::visit([](auto&& x) {f(x);}, something);
This creates a closure based on a template which generates code to do dispatch at compile-time. Effectively, it works as though we did
void f(A a) {
std::cout << a.name << std::endl;
}
void f(B b) {
std::cout << b.type << std::endl;
}
void f(C c) {
std::cout << c.age << std::endl;
}
struct F {
template<typename T>
void operator()(T x) {
f(x);
}
};
int main() {
std::variant<A, B, C> something{B{}};
std::visit(F(), something);
}
Which would force the C++ compiler, during template expansion, to produce something like
void f(A a) {
std::cout << a.name << std::endl;
}
void f(B b) {
std::cout << b.type << std::endl;
}
void f(C c) {
std::cout << c.age << std::endl;
}
struct F {
void operator()(A x) {
f(x);
}
void operator()(B x) {
f(x);
}
void operator()(C x) {
f(x);
}
};
int main() {
std::variant<A, B, C> something{B{}};
std::visit(F(), something);
}
If you want to eliminate the lambda wrapper, you need a single callable object that can be passed as an argument, and a function pointer will not suffice, as a function pointer can't do overload resolution. We can always make a functor object explicitly.
struct F {
void operator()(A a) {
std::cout << a.name << std::endl;
}
void operator()(B b) {
std::cout << b.type << std::endl;
}
void operator()(C c) {
std::cout << c.age << std::endl;
}
};
int main() {
std::variant<A, B, C> something{B{}};
std::visit(F(), something);
}
It's up to you whether or not you consider this cleaner than the previous approach. On the one hand, it's more like the traditional OOP visitor pattern, in that we have an object doing the visiting. On the other hand, it would be nice if we could pass the name of a function and have C++ understand what we mean, but that would either require special C++ syntax for std::visit or runtime-dispatch in the form of multimethods. Either way, it's unlikely to happen soon, or at all.
A variation of #Silvio's answer is to create a template overload type that inherits from your functions:
#include <variant>
#include <iostream>
struct A {
std::string name = "spencer";
};
struct B {
std::string type = "person";
};
struct C {
double age = 5;
};
template<typename...Func>
struct overload : Func... {
using Func::operator()...;
};
template<typename...Func> overload(Func...) -> overload<Func...>;
int main()
{
overload ovld {
[](A a) { std::cout << a.name << std::endl; },
[](B b) { std::cout << b.type << std::endl; },
[](C c) { std::cout << c.age << std::endl; }
};
std::variant<A, B, C> something{B{}};
std::visit(ovld, something);
}
Until C++17, the deduction guide is necessary for aggregate CTAD (Class Template Argument Deduction)
Is there a simpler way?
Well, there might be a syntactically more streamlined way:
You can use overloaded{} from the cppreference example right inside the std::visit:
std::visit(overloaded{
[](A a) { std::cout << a.name << std::endl; },
[](B b) { std::cout << b.type << std::endl; },
[](C c) { std::cout << c.age << std::endl; }
}, something);
here, the overloaded implementation is pretty simple and the only thing of interest may be the deduction guide in case you're not familiar with C++17 deduction guides yet
Or better yet, you can do a little twist with the same overloaded struct and make this possible:
something| match {
[](A a) { std::cout << a.name << std::endl; },
[](B b) { std::cout << b.type << std::endl; },
[](C c) { std::cout << c.age << std::endl; }
};
I personally like the latter version for it's more streamlined and it resembles the match clause from some other languages.
The implementation is actually pretty straightforward, the only 2 changes are:
you rename overloaded to whatever you like, here it's match
you overload operator| for it to work
template <typename... Ts, typename... Fs>
constexpr decltype(auto) operator| (std::variant<Ts...> const& v, match<Fs...> const& match) {
return std::visit(match, v);
}
I have this and a little more syntactic sugar (such as |is and |as "operator-lookalikes" for variant and any) in this repo :)

Can you call different constructors based on different template parameters

Is there an way to call different constructors of same class based on different template parameter.
template<class T>
class X {
public:
T a;
X<char>() {
std::cout << "char ctor called" << std::endl;
}
X<int>() {
std::cout << "int ctor called" << std::endl;
}
};
int main() {
X<char> x;
X<int> y;
}
I think constructors in the class are not valid, but is there any other way to do that?
There are several ways:
(full) specialization of the member:
template<class T>
class X {
public:
T a;
X();
};
template <>
X<char>::X() : a('\0') { std::cout << "char ctor called" << std::endl; }
template <>
X<int>::X() : a(0) { std::cout << "int ctor called" << std::endl; }
Specialize the whole class (so requires to duplicate some code though)
template<class T>
class X;
template <>
class X<char> {
public:
char a;
X() : a('\0') { std::cout << "char ctor called" << std::endl; }
};
template <>
class X<int> {
public:
int a;
X() : a(0) { std::cout << "int ctor called" << std::endl; }
};
if constexpr of C++17 (but doesn't handle initializer list):
template<class T>
class X {
public:
T a;
X() : a(0) {
if constexpr (std::is_same_v<char, T>) {
std::cout << "char ctor called" << std::endl;
} else if constexpr (std::is_same_v<int, T>) {
std::cout << "int ctor called" << std::endl;
}
}
};
requires for C++20:
template<class T>
class X {
public:
T a;
X() requires(std::is_same_v<char, T>) : a('\0') {
std::cout << "char ctor called" << std::endl;
}
X() requires(std::is_same_v<int, T>) : a(0) {
std::cout << "int ctor called" << std::endl;
}
};
You can use if constexpr:
template <class T>
class X {
public:
// ...
X()
{
if constexpr (std::is_same_v<T, int>) {
// ...
} else if constexpr (std::is_same_v<T, char>) {
// ...
} else {
// ...
}
}
};
Just another alternative - tag dispatch:
template<class T>
class X {
public:
// ...
X() : X(Tag<T>{}) {}
private:
template<class> struct Tag {};
X(Tag<char>) {
// ...
}
X(Tag<int>) {
// ...
}
template<class U> X(Tag<U>) {
// ...
}
};
Yes,see http://www.cplusplus.com/doc/oldtutorial/templates/
You can do this:
template<class T>
class X {
public:
T a;
X() {
std::cout << "basic template\n" ;
}
};
template<>
class X<char> {
public:
char a;
X() {
std::cout << "char ctor called\n" ;
}
};
template<>
class X<int> {
public:
int a;
X() {
std::cout << "int ctor called\n";
}
};
int main(){
X<int> xint;
X<char> xchar;
X<string> xstring;
return 0;
}
You will see in the output window:
int ctor called
char ctor called
basic template

Overloading function templates and inherited arguments

This code:
#include <iostream>
class A {};
class B : public A {};
class C {
public:
template <typename T>
void x(const T& t) {
std::cout << "template" << std::endl;
}
void x(const A*& a) {
std::cout << "a" << std::endl;
}
void x(const int& a) {
std::cout << "int" << std::endl;
}
template <typename T>
void y(T t) {
std::cout << "template" << std::endl;
}
void y(A* a) {
std::cout << "a" << std::endl;
}
void y(int a) {
std::cout << "int" << std::endl;
}
template <typename T>
void z(const T& t) {
std::cout << "template" << std::endl;
}
};
// Does not compile
// template <>
// void C::z(const A*& a) {
// std::cout << "a" << std::endl;
// }
template <>
void C::z(const int& a) {
std::cout << "int" << std::endl;
}
int main(int argc, char** argv) {
C c;
c.x(new A());
c.x(new B());
c.x(1);
c.y(new A());
c.y(new B());
c.y(1);
c.z(new A());
c.z(new B());
c.z(1);
}
Prints:
template
template
int
a
template
int
template
template
int
I have the following questions about that:
Why does void C::z(const int& a) compile but void C::z(const A*& a) does not?
What is a reasonable solution to problem? I need to have a templated function for generically handling a wide variety of arguments, but a large set of classes with a common base needs to be handled specifically. I need some approach that will print a a int.
Edit: Thanks to the suggestion of #AndyG I was able to resolve this with some type_traits and the code below:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <iostream>
class A {};
class B : public A {};
class C {
public:
template <typename T>
typename boost::disable_if<boost::is_base_of<A, typename boost::remove_pointer<T>::type>, void>::type x(const T& t) {
std::cout << "template" << std::endl;
}
void x(A*const& a) {
std::cout << "a" << std::endl;
}
void x(const int& a) {
std::cout << "int" << std::endl;
}
};
int main(int argc, char** argv) {
C c;
c.x(new A());
c.x(new B());
c.x(1);
}
The answer is because a const on a pointer type is a little weird.
What you want is this:
template <>
void C::z( A*const& a) {
std::cout << "a" << std::endl;
}
const needs to be read right to left. Since z accepts a T&, when you want to specialize for A* you need to place the const after A* instead of in front.
Demo

Overloaded function template matching template instead of base class when called with subclass

Consider the following code:
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
virtual ~A() {
}
};
class B : public A {
};
void foo(A& a) {
cout << "A&" << endl;
}
void foo(const A& a) {
cout << "const A&" << endl;
}
void foo(A* a) {
cout << "A*" << endl;
}
void foo(const A* a) {
cout << "const A*" << endl;
}
template <class T>
void foo(T& a) {
cout << "T&" << endl;
}
template <class T>
void foo(const T& a) {
cout << "const T&" << endl;
}
template <class T>
void foo(T* a) {
cout << "T*" << endl;
}
template <class T>
void foo(const T* a) {
cout << "const T*" << endl;
}
int main(int argc, char** argv) {
B a;
foo(a);
B& b = a;
foo(b);
B* c = &a;
foo(c);
const B& d = a;
foo(d);
const B* e = &a;
foo(e);
return EXIT_SUCCESS;
}
Produces the following output:
T&
T&
T*
const T&
const T*
This output surprised me because I thought the function that was the closest match would be the one invoked. So I was expecting the output:
A&
A&
A*
const A&
const A*
Can someone explain why the template functions overloads are chosen over the base class overloads when I pass in a subclass (B) of the base class (A)?
This is the expected behavior. When you call foo(a); a is a B. So we would need a implicit conversion from a B to a A in order to call void foo(A& a). However since you also have
template <class T>
void foo(T& a) {
cout << "T&" << endl;
}
The template gets stamped out and you get void foo(B& a). This is a direct match and requires no conversion. This is the best function so that is why it is picked. This is the same for all of the other functions as well as T gets deduced to B which gives a better match then all of the A functions.
If you want to stop this you could use std::enable_if and check if the type is a derived class with std::is_base_of

C++11 call member function on template parameter pack of base classes if present

I have checked questions that are similar. This is close, but not a duplicate.
In essence I want to call a function on a parameter pack of base classes if present. I have a C++11 way of doing this that works, but it does not feel satisfactory to me.
Can someone offer a better [i.e. better performance and less boilerplate code]:
source code:
#include <iostream>
#include <type_traits>
using namespace std;
// a class initialised with an int that can't do it
struct A
{
A(int a) : _a(a) { }
void report() const { std::cout << _a << std::endl; }
private:
int _a;
};
// a class initialised with a string that can do it
struct B
{
B(std::string s) : _b (move(s)) { }
void report() const { std::cout << _b << std::endl; }
void do_it() { std::cout << "B did it with " << _b <<"!" << std::endl; }
private:
string _b;
};
// a class initialised with an int that can do it
struct D
{
D(int d) : _d(d) { }
void report() const { std::cout << _d << std::endl; }
void do_it() { std::cout << "D did it with " << _d <<"!" << std::endl; }
private:
int _d;
};
// a class initialised with a string that can't do it
struct E
{
E(std::string s) : _e(move(s)) { }
void report() const { std::cout << _e << std::endl; }
private:
string _e;
};
// a function enabled only if T::do_it is a member function pointer
// the bool is there just to make this function more attractive to the compiler
// than the next one, below
template<class T>
auto do_it(T& t, bool)
-> typename std::enable_if<std::is_member_function_pointer<decltype(&T::do_it)>::value, void>::type
{
t.do_it();
}
// a catch-all function called when do_it<T> is not valid
// the ... is less attractive to the compiler when do_it<T>(T&, bool) is available
template<class T>
void do_it(T& t, ...)
{
}
// a compound class derived from any number of classes - I am so lazy I work hard at
// being lazy.
template<class...Templates>
struct C : public Templates...
{
// construct from a parameter pack of arbitrary arguments
// constructing each base class with one argument from the pack
template<class...Args>
C(Args&&...args)
: Templates(std::forward<Args>(args))...
{
}
// private implementation of the dispatch mechanism here...
private:
// this will call ::do_it<T>(T&, bool) if T::do_it is a member function of T, otherwise
// calls ::do_it<T>(T&, ...)
template<class T>
void may_do_it()
{
::do_it(static_cast<T&>(*this), true);
}
// calls may_do_it for the last class in the parameter pack
template<typename T1>
void multi_may_do_it()
{
may_do_it<T1>();
}
// general case for calling do_it on a parameter pack of base classes
template<typename T1, typename T2, typename...Rest>
void multi_may_do_it()
{
may_do_it<T1>();
multi_may_do_it<T2, Rest...>();
}
// calls may_do_it for the last class in the parameter pack
template<typename T1>
void multi_report() const
{
static_cast<const T1&>(*this).report();
}
// general case for calling do_it on a parameter pack of base classes
template<typename T1, typename T2, typename...Rest>
void multi_report() const
{
static_cast<const T1&>(*this).report();
multi_report<T2, Rest...>();
}
// the functions we actually wish to expose here...
public:
// disptach T::do_it for each valid T in base class list
void do_it() {
multi_may_do_it<Templates...>();
}
// dispatch T::report, which must exist for each base class
void report() const {
cout << "-- all base classes reporting:" << endl;
multi_report<Templates...>();
cout << "-- all base classes reported" << endl;
}
};
int main()
{
C<A,B, D, E> c(10, "hello", 7, "goodbye");
c.report(); // all base classes must report
c.do_it(); // all base classes that can do_it, must.
return 0;
}
output:
Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
Executing the program....
$demo
-- all base classes reporting:
10
hello
7
goodbye
-- all base classes reported
B did it with hello!
D did it with 7!
I think this is about as boilerplate-free as you can make it.
// a function enabled only if T::do_it is a member function pointer
template<class T>
auto do_it(T* t)
-> typename std::enable_if<std::is_member_function_pointer<decltype(&T::do_it)>::value, void>::type
{
t->do_it();
}
// a catch-all function called when do_it<T> is not valid
// the const void * is less attractive to the compiler when do_it<T>(T*) is available
template<class T>
void do_it(const void *)
{
}
// a compound class derived from any number of classes - I am so lazy I work hard at
// being lazy.
template<class...Templates>
struct C : public Templates...
{
//constructor omitted
private:
using expander = int[];
public:
// disptach T::do_it for each valid T in base class list
void do_it() {
(void) expander{ 0, (::do_it<Templates>(this), 0)...};
}
// dispatch T::report, which must exist for each base class
void report() const {
cout << "-- all base classes reporting:" << endl;
(void) expander{ 0, (Templates::report(), 0)...};
cout << "-- all base classes reported" << endl;
}
};
Demo.