Template argument deduction

B

blaz.bratanic

Would it be possible to rewrite the code below, to avoid explicit template argument specification?

#include <iostream>

struct A {
enum {
pass_by_reference = true
};

A() { std::cout << "A constructor." << std::endl; }
A(A const& other) { std::cout << "A copy constructor." << std::endl; }
void print() { std::cout << "Print A" << std::endl; }
};

struct B {
enum {
pass_by_reference = false
};

B() { std::cout << "B constructor." << std::endl; }
B(B const& other) { std::cout << "B copy constructor." << std::endl; }
void print() { std::cout << "Print B" << std::endl; }
};

template <bool B, class T> struct cond {
typedef T type;
};

template <class T> struct cond<true, T> {
typedef T& type;
};

template <typename T>
void foo(typename cond<T::pass_by_reference, T>::type a) {
a.print();
}

int main() {
A a;
B b;

foo<A>(a);
foo<B>(b);
}
 
A

Alf P. Steinbach

Would it be possible to rewrite the code below, to avoid explicit template argument specification?

#include <iostream>

struct A {
enum {
pass_by_reference = true
};

A() { std::cout << "A constructor." << std::endl; }
A(A const& other) { std::cout << "A copy constructor." << std::endl; }
void print() { std::cout << "Print A" << std::endl; }
};

struct B {
enum {
pass_by_reference = false
};

B() { std::cout << "B constructor." << std::endl; }
B(B const& other) { std::cout << "B copy constructor." << std::endl; }
void print() { std::cout << "Print B" << std::endl; }
};

template <bool B, class T> struct cond {
typedef T type;
};

template <class T> struct cond<true, T> {
typedef T& type;
};

template <typename T>
void foo(typename cond<T::pass_by_reference, T>::type a) {
a.print();
}

int main() {
A a;
B b;

foo<A>(a);
foo<B>(b);
}

I can't see any good reason to do the above, and many good reasons to
not do it.

But re the purely technical, yes.

Code:
#include <iostream>

struct A {
typedef A& Formal_arg;

A() { std::cout << "A constructor." << std::endl; }
A(A const& ) { std::cout << "A copy constructor." << std::endl; }
void print() { std::cout << "Print A" << std::endl; }
};

struct B {
typedef B Formal_arg;

B() { std::cout << "B constructor." << std::endl; }
B(B const& ) { std::cout << "B copy constructor." << std::endl; }
void print() { std::cout << "Print B" << std::endl; }
};


template< class Type >
void real_foo( typename Type::Formal_arg a )
{ a.print(); }

template< class Type >
void foo( Type& a )
{ real_foo<Type>( a ); }

int main() {
A a;
B b;

foo(a);
foo(b);
}

Cheers & hth.,

- Alfd
 
B

blaz.bratanic

Dne torek, 29. oktober 2013 05:26:46 UTC+1 je oseba Alf P. Steinbach napisala:
Would it be possible to rewrite the code below, to avoid explicit template argument specification?

#include <iostream>

struct A {
pass_by_reference = true


A() { std::cout << "A constructor." << std::endl; }
A(A const& other) { std::cout << "A copy constructor." << std::endl; }
void print() { std::cout << "Print A" << std::endl; }


struct B {
pass_by_reference = false


B() { std::cout << "B constructor." << std::endl; }
B(B const& other) { std::cout << "B copy constructor." << std::endl; }
void print() { std::cout << "Print B" << std::endl; }


template <bool B, class T> struct cond {
typedef T type;


template <class T> struct cond<true, T> {
typedef T& type;


template <typename T>
void foo(typename cond<T::pass_by_reference, T>::type a) {



int main() {



I can't see any good reason to do the above, and many good reasons to

not do it.



But re the purely technical, yes.



Code:
#include <iostream>



struct A {

typedef A& Formal_arg;



A() { std::cout << "A constructor." << std::endl; }

A(A const& ) { std::cout << "A copy constructor." << std::endl; }

void print() { std::cout << "Print A" << std::endl; }

};



struct B {

typedef B Formal_arg;



B() { std::cout << "B constructor." << std::endl; }

B(B const& ) { std::cout << "B copy constructor." << std::endl; }

void print() { std::cout << "Print B" << std::endl; }

};





template< class Type >

void real_foo( typename Type::Formal_arg a )

{ a.print(); }



template< class Type >

void foo( Type& a )

{ real_foo<Type>( a ); }



int main() {

A a;

B b;



foo(a);

foo(b);

}



Cheers & hth.,



- Alfd

Thank you for your reply!

What would be the reasons not to do this?

thanks
 
Ö

Öö Tiib

What would be the reasons not to do this?

We pass "in" parameters either by copy, by move or by reference/pointer to const.

We pass "out" or "in-out" parameters by reference/pointer to non-const.

Deciding if objects of it are needed as "in", "out" or "in-out" parameters in functions
feels to be above responsibilities of class. So do not give that responsibility to class.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top