Reputation: 157
I am trying to create a variable type called variant (kind of like to one in VisualBasic) where it can change variable types (not really, but it will change which one will get returned). Here is my code:
#include <string>
using namespace std;
class Variant{
private:
int int_v;
char char_v;
bool bool_v;
string string_v;
char type;
public:
void set(int);
void set(char);
void set(bool);
void set(string);
auto get();
Variant();
};
Variant::Variant(){
int_v = 0;
char_v = ' ';
bool_v = false;
string_v = "";
type = ' ';
}
void Variant::set(int value){
int_v = value;
char_v = ' ';
bool_v = false;
string_v = "";
type = 'i';
}
void Variant::set(char value){
char_v = value;
int_v = 0;
bool_v = false;
string_v = "";
type = 'c';
}
void Variant::set(bool value){
bool_v = value;
int_v = 0;
char_v = ' ';
string_v = "";
type = 'b';
}
void Variant::set(string value){
string_v = value;
int_v = 0;
char_v = ' ';
bool_v = false;
type = 's';
}
auto Variant::get(){
if(type == 'i') return int_v;
else if(type == 'c') return char_v;
else if(type == 'b') return bool_v;
else if(type == 's') return string_v;
else return -1;
}
int main(int argc, char *argv[]){
return 0;
}
What this code is supposed to do is something like this:
#include <iostream>
#include "Variant.h"
using namespace std;
int main(int argc, char *argv[]){
Variant var;
var.set(5); //set var to 5
cout<<var.get()<<endl; //print var (5)
var.set('a'); //set var to 'a'
cout<<var.get()<<endl; //print var (a)
var.set(true); //set var to true
cout<<var.get()<<endl; //print var (true)
var.set("Hello, World!"); //set var to "Hello, World!"
cout<<var.get()<<endl; //print var (Hello, World!)
return 0;
}
But g++ tells me:
Variant.h:17:12: error: ISO C++ forbids declaration of ‘get’ with no type [-fpermissive]
auto get();
^
Variant.h:17:12: error: storage class specified for ‘get’
All help is appreciated! Thanks!
Upvotes: 1
Views: 4261
Reputation: 800
Your return statements in get
are returning different types.
According to here:
Generalized return type deduction now works even with more complex function bodies containing more than one return statement, as long as all return statements return the same type.
Edit:
See Matt McNabb's answer for solving this error with templates.
Upvotes: 1
Reputation: 141554
The return type must be deducible at compile-time, similar to a template parameter. The function cannot return different types depending on run-time properties such as what the variant currently contains.
You don't really have much option other than variations of:
template<typename T>
T get() const;
for which you will have to specify the template parameter when calling. (I don't see what is gained by returning a tuple
and then having to call get<int>
on that anyway...)
Here is fuller sample code:
// In class definition
template<typename T> T get() const;
// Outside
template<> char Variant::get<char>() const { return char_v; }
template<> int Variant::get<int>() const { return int_v; }
template<> bool Variant::get<bool>() const { return bool_v; }
template<> string Variant::get<string>() const { return string_v; }
Upvotes: 2