template<typename T> //T is a type which supports the dereference operator
void foo(T& param){
	//the type of expression *param is defined at compile time
	U = *param; //U is the type which *param returns
}

My question is: How can I implicitly determine the return type of performing an operation on an inputted generic type without explicitly indicating it in the function call? The return type of an operation is defined for each type I might use as a param, and is known at compile time.

for example

std::vector<int>::iterator svii;
foo(svii);
//type T is an iterator for a vector of ints
//type U would be int, the type returned by dereferencing the iterator, but how do I make the compiler determine that at compile time without specifiying it explicitly?

Recommended Answers

All 7 Replies

I could be wrong ;), but I don't think it's possible. I believe you have to explicitly give the return type, like so:

template <typename U, typename T>
U foo(T& param) {
    return *param;
}
// ...
int n = foo<int>(i);

Thanks for the help, but that's exactly what I want to avoid.
On a related note, is it possible to have an stl container hold a templated class without discriminating the type of the template? Like this:

template<typename T>
struct wrapper{
	T content;
};
int main(){
	wrapper<int> wi;
	wrapper<double> wd;
	wrapper<string> ws;
	vector<wrapper> magicVector; //holds any type of wrapper
	magicVector.push_back(wi);
	magicVector.push_back(wd);
	magicVector.push_back(ws);

	magicVector[1].content; //automatically returns the correct type based on the type of wrapper at position 1
}

Is it possible for me to do this in C++ while maintaining type safety and not resorting to void pointers?

> that's exactly what I want to avoid
That's what I figured. ;)

As for your second question, it does not seem possible. The point here is that wrapper is not a type. Only wrapper<int>, etc. are types. So you cannot have a vector<wrapper>. You can do something similar with a common base class and virtual functions, but you probably know that.

Thanks for the responce, but you're right. I don't want a vector holding one particular type of wrapper. I want a vector that can hold EVERY type of wrapper, all at once.
maybe I can have something like

class parent{
public:
virtual void foo(){}
};

template<typename T>
class child : public parent{
public:
T foo(){
return member;
}
private:
T member;
};

sorry for no formatting, tab doesn't seem to work in firefox.

That idea still won't work. I was thinking of something like the code below. Unfortunately, I can't see how you can template the return values since the parent class (which defines the virtual function) cannot be templated; otherwise it will not be the same type for each child, since parent<int> is a different type from parent<double>.

#include <iostream>
#include <vector>
#include <string>

class parent{
public:
  virtual void show() = 0;
};

template<typename T>
class child : public parent {
public:
  child(T m) : member(m) { }
  void show(){ std::cout << member << '\n'; }
private:
  T member;
};

typedef std::vector<parent*> Vec;
typedef Vec::iterator VecI;

int main() {
    Vec v;
    v.push_back(new child<int>(123));
    v.push_back(new child<double>(1.23));
    v.push_back(new child<std::string>("howdy"));
    for (VecI i = v.begin(); i != v.end(); ++i)
        (*i)->show();
std::cin.get();
}

PLEASE READ AND RESPOND, THANK YOU!

#include <iostream>
#include <vector>
#include <string>

class parent{
public:
  template<typename U>
  U& getMember()=0;
};

template<typename T>
class child : public parent {
public:
  child(T m) : member(m) { }
  T& getMember{
    return member;
  }
private:
  T member;
};

typedef std::vector<parent*> Vec;
typedef Vec::iterator VecI;

int main() {
    Vec v;
    v.push_back(new child<int>(123));
    v.push_back(new child<double>(1.23));
    v.push_back(new child<std::string>("howdy"));
    for (VecI i = v.begin(); i != v.end(); ++i)
        (*i)->getMember();
std::cin.get();
}

How's that for an idea? Thank you for inspiring it, now to see if my compiler likes it.

It's a good try, but I don't think it'll work!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.