开发者

Using Function Templates

I have created a structure of different data types and i want to return each type of data. does this can be done using a function template which takes a different data argument not included in structure or no arguments?

I have something like this,

struct mystruct{
int _int;
char _c;
string _str
};

In function template(int i)
{
     mystruct s;

      switch (getInput)
     {
      case 1:
        return s._int;
    开发者_Python百科  case 2:
        return s._c;
      case 3:
        return s._str;
   }   
} 

void main()  

{
   int getInput = 1;
   //pass getInput value to function template
}


Yes:

template<class T>
T f() {
  return 0; // for the sake of example
}

int main() {
  return f<int>(); // specify the template parameter
}

template<class T>
vector<T> another_example();
// use another_example<int>() which returns a vector<int>


The following is building of GMan's (now deleted) interpretation of your very confusing question:

struct some_data
{
    int i;
    char c;
    std::string s;
};

template< typename T > struct Getter;
template<> struct Getter<int> { static int& get(some_data& data) {return data.i} };
template<> struct Getter<char> { static char& get(some_data& data) {return data.c} };
template<> struct Getter<std::string> { static std::string& get(some_data& data) {return data.s} };

template< typename T >
inline T get(some_data& data) {return Getter<T>::get(data);}

I'm not sure. though, whether this is what you were asking for.


What I understand is the following: I want to create a function whose return type depends on its parameter(s). Well, technically, you can't.

  1. When those return types are classes with a common ancestor, you could return a pointer to that ancestor. It's not quite the same thing, but it works. Unfortunately, two of the return types are char and int, which are not classes in first place.

  2. When those return types are plain old data types, you could return a tagged union. Unfortunately, one of the return types is std::string, which is not a plain old data type.

  3. A solution that works with any type but is incredibly hacker-ish is to use void*. Well, unfortunately, void* is error-prone. Whoever maintains your code will curse you forever if you use void*.

  4. A final solution (pun not intended) that works is to use boost::variant. It's quite complicated, but at least it's safe (unlike void*), because type errors can be checked at compile time.


Here is another interpretation that doesn't use templates:

struct some_data
{
    int i;
    char c;
    std::string s;

    void get(int& value) const
         { value = i; }
    void get(char& value) const
         { value = c; }
    void get(& value) const
         { value = s; }
};

// ...
some_data received_data;
int k;
received_data.get(k);
//...
received_data.s = "Hello";
std::string world;
received_data.get(world);
std::cout << world << std::endl;

The compiler will generate the correct method calls based on the type of the argument. This can be translated into non-member functions:

void Get_Some_Data(char& value, const some_data& sd)
{
    value = sd.c;
    return;
}


void Get_Some_Data(int& value, const some_data& sd)
{
    value = sd.i;
    return;
}

void Get_Some_Data(std::string& value, const some_data& sd)
{
    value = sd.s;
    return;
}

//...
char f;
Get_Some_Data(f, received_data);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜