Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template type deduction of reference

I've been playing around with type deduction/printing using templates with code of the form:

#include <iostream>
template <typename T>
class printType {};

template <typename T>
std::ostream& operator<<(std::ostream& os, const printType<T>&)
{
    os << "SomeType"; return os;
}  

template <typename T>
std::ostream& operator<<(std::ostream& os, const printType<T*>&)
{
    os << printType<T>() << "*"; return os;
}  

template <typename T>
std::ostream& operator<<(std::ostream& os, const printType<T&>&)
{
    os << printType<T>() << "&"; return os;
}  
// etc... and can call on a variable through

template <typename T>
printType<T> print(T) { return printType<T>(); }  

int main()
{
    int a = 7;
    int *p = &a;
    int &r = a;

    //OK: return SomeType*
    std::cout << "type of p: " << print(p) << std::endl;
    //Hmmmm: returns SomeType <- (no &: can I get around this?)
    std::cout << "type of r: " << print(r) << std::endl;
}

I am wondering whether or not I can get the last line to return int& , that is, either:
(i) have the function template print deduce the type of it's argument as int& or somehow work out it should return a printType<T&> when I pass it r; or
(ii)whether this is unavoidable because of the way the variable is passed to the function.

Are there any ways around this by changing the form of print or using some other template trickery? If solutions exists, I'd prefer non-C++0x, but is always good to see what short cuts will, if not already, be available in the future.

like image 693
dbeacham Avatar asked Sep 24 '10 11:09

dbeacham


People also ask

What is template argument deduction?

Template argument deduction is used in declarations of functions, when deducing the meaning of the auto specifier in the function's return type, from the return statement.

What is type deduction?

Type inference or deduction refers to the automatic detection of the data type of an expression in a programming language. It is a feature present in some strongly statically typed languages. In C++, the auto keyword(added in C++ 11) is used for automatic type deduction.

What is the difference between Typename and class in template?

There is no difference between using <typename T> OR <class T> ; i.e. it is a convention used by C++ programmers.


1 Answers

There is no way to work this around. An expression p, where p names a reference, always has the type the reference refers to. No expression ever has type T&. So you cannot detect whether an expression originated from a reference or not.

This cannot be done with C++0x either. It's a deep principle of C++ that there are no expressions that have reference type. You can write decltype(r) to get the type of what r names instead of what type the expression r has. But you will not be able to write print(r), unless print is a macro of course, but I don't see why you would go that horrible road.

like image 173
Johannes Schaub - litb Avatar answered Oct 02 '22 02:10

Johannes Schaub - litb