Multiple return type from function - C++
up vote
-1
down vote
favorite
Is there any way (conventional or no) to get a choice between multiple specified return types from a function. For example:
/* Concept code... */
class var {
public:
union {
bool _bool;
int _int;
char* _char_pointer;
} primitive_value;
std::string type;
var(bool arg) { primitive_value._bool = arg; type = "bool"; }
var(int arg) { primitive_value._int = arg; type = "int"; }
var(char* arg) { primitive_value._char_pointer = arg; type = "char*"; }
// Function/ method that could return `bool`, `int` or `char*`
<bool, int, char*> valueOf() const {
if (type == "bool") return primitive_value._bool;
else if (type == "int") return primitive_value._int;
else if (type == "char*") return primitive_value._char_pointer;
}
};
There is a reference to a similar question here I've seen that suggested using void*
pointers or union
's but I have yet to fully understand how those work.
No container types (such as std::any
, std::optional
, std::variant
) are allowed because I want to know if there is an alternative to those as well.
To add on, this is all in the name of curiosity. Currently I am searching the optional
and variant
header files to know how the feature I'm asking for was implemented but no luck so far.
I'm hoping the platform here could have a practical solution to this potential problem.
c++ c++17
|
show 10 more comments
up vote
-1
down vote
favorite
Is there any way (conventional or no) to get a choice between multiple specified return types from a function. For example:
/* Concept code... */
class var {
public:
union {
bool _bool;
int _int;
char* _char_pointer;
} primitive_value;
std::string type;
var(bool arg) { primitive_value._bool = arg; type = "bool"; }
var(int arg) { primitive_value._int = arg; type = "int"; }
var(char* arg) { primitive_value._char_pointer = arg; type = "char*"; }
// Function/ method that could return `bool`, `int` or `char*`
<bool, int, char*> valueOf() const {
if (type == "bool") return primitive_value._bool;
else if (type == "int") return primitive_value._int;
else if (type == "char*") return primitive_value._char_pointer;
}
};
There is a reference to a similar question here I've seen that suggested using void*
pointers or union
's but I have yet to fully understand how those work.
No container types (such as std::any
, std::optional
, std::variant
) are allowed because I want to know if there is an alternative to those as well.
To add on, this is all in the name of curiosity. Currently I am searching the optional
and variant
header files to know how the feature I'm asking for was implemented but no luck so far.
I'm hoping the platform here could have a practical solution to this potential problem.
c++ c++17
8
std::variant
just does what you are asking. you could implement it yourself if you really want
– M.M
Nov 19 at 12:34
6
The example code you show looks like a bad design. And why can't you use e.g.std::any
orstd::variant
? How about templates (possibly with specialization)?
– Some programmer dude
Nov 19 at 12:34
2
how would you call the function? Lets say you make it return different types, then also the caller has to be able to handle different types. Whatever you do it will be either complicated or broken or both. I agree that this is probably not the best design
– user463035818
Nov 19 at 12:37
2
See this: arne-mertz.de/2018/05/modern-c-features-stdvariant-and-stdvisit
– palotasb
Nov 19 at 12:44
1
the problem is that you can't compare strings at compile time
– Stack Danny
Nov 19 at 12:59
|
show 10 more comments
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
Is there any way (conventional or no) to get a choice between multiple specified return types from a function. For example:
/* Concept code... */
class var {
public:
union {
bool _bool;
int _int;
char* _char_pointer;
} primitive_value;
std::string type;
var(bool arg) { primitive_value._bool = arg; type = "bool"; }
var(int arg) { primitive_value._int = arg; type = "int"; }
var(char* arg) { primitive_value._char_pointer = arg; type = "char*"; }
// Function/ method that could return `bool`, `int` or `char*`
<bool, int, char*> valueOf() const {
if (type == "bool") return primitive_value._bool;
else if (type == "int") return primitive_value._int;
else if (type == "char*") return primitive_value._char_pointer;
}
};
There is a reference to a similar question here I've seen that suggested using void*
pointers or union
's but I have yet to fully understand how those work.
No container types (such as std::any
, std::optional
, std::variant
) are allowed because I want to know if there is an alternative to those as well.
To add on, this is all in the name of curiosity. Currently I am searching the optional
and variant
header files to know how the feature I'm asking for was implemented but no luck so far.
I'm hoping the platform here could have a practical solution to this potential problem.
c++ c++17
Is there any way (conventional or no) to get a choice between multiple specified return types from a function. For example:
/* Concept code... */
class var {
public:
union {
bool _bool;
int _int;
char* _char_pointer;
} primitive_value;
std::string type;
var(bool arg) { primitive_value._bool = arg; type = "bool"; }
var(int arg) { primitive_value._int = arg; type = "int"; }
var(char* arg) { primitive_value._char_pointer = arg; type = "char*"; }
// Function/ method that could return `bool`, `int` or `char*`
<bool, int, char*> valueOf() const {
if (type == "bool") return primitive_value._bool;
else if (type == "int") return primitive_value._int;
else if (type == "char*") return primitive_value._char_pointer;
}
};
There is a reference to a similar question here I've seen that suggested using void*
pointers or union
's but I have yet to fully understand how those work.
No container types (such as std::any
, std::optional
, std::variant
) are allowed because I want to know if there is an alternative to those as well.
To add on, this is all in the name of curiosity. Currently I am searching the optional
and variant
header files to know how the feature I'm asking for was implemented but no luck so far.
I'm hoping the platform here could have a practical solution to this potential problem.
c++ c++17
c++ c++17
edited Nov 19 at 13:06
asked Nov 19 at 12:32
Lapys
396313
396313
8
std::variant
just does what you are asking. you could implement it yourself if you really want
– M.M
Nov 19 at 12:34
6
The example code you show looks like a bad design. And why can't you use e.g.std::any
orstd::variant
? How about templates (possibly with specialization)?
– Some programmer dude
Nov 19 at 12:34
2
how would you call the function? Lets say you make it return different types, then also the caller has to be able to handle different types. Whatever you do it will be either complicated or broken or both. I agree that this is probably not the best design
– user463035818
Nov 19 at 12:37
2
See this: arne-mertz.de/2018/05/modern-c-features-stdvariant-and-stdvisit
– palotasb
Nov 19 at 12:44
1
the problem is that you can't compare strings at compile time
– Stack Danny
Nov 19 at 12:59
|
show 10 more comments
8
std::variant
just does what you are asking. you could implement it yourself if you really want
– M.M
Nov 19 at 12:34
6
The example code you show looks like a bad design. And why can't you use e.g.std::any
orstd::variant
? How about templates (possibly with specialization)?
– Some programmer dude
Nov 19 at 12:34
2
how would you call the function? Lets say you make it return different types, then also the caller has to be able to handle different types. Whatever you do it will be either complicated or broken or both. I agree that this is probably not the best design
– user463035818
Nov 19 at 12:37
2
See this: arne-mertz.de/2018/05/modern-c-features-stdvariant-and-stdvisit
– palotasb
Nov 19 at 12:44
1
the problem is that you can't compare strings at compile time
– Stack Danny
Nov 19 at 12:59
8
8
std::variant
just does what you are asking. you could implement it yourself if you really want– M.M
Nov 19 at 12:34
std::variant
just does what you are asking. you could implement it yourself if you really want– M.M
Nov 19 at 12:34
6
6
The example code you show looks like a bad design. And why can't you use e.g.
std::any
or std::variant
? How about templates (possibly with specialization)?– Some programmer dude
Nov 19 at 12:34
The example code you show looks like a bad design. And why can't you use e.g.
std::any
or std::variant
? How about templates (possibly with specialization)?– Some programmer dude
Nov 19 at 12:34
2
2
how would you call the function? Lets say you make it return different types, then also the caller has to be able to handle different types. Whatever you do it will be either complicated or broken or both. I agree that this is probably not the best design
– user463035818
Nov 19 at 12:37
how would you call the function? Lets say you make it return different types, then also the caller has to be able to handle different types. Whatever you do it will be either complicated or broken or both. I agree that this is probably not the best design
– user463035818
Nov 19 at 12:37
2
2
See this: arne-mertz.de/2018/05/modern-c-features-stdvariant-and-stdvisit
– palotasb
Nov 19 at 12:44
See this: arne-mertz.de/2018/05/modern-c-features-stdvariant-and-stdvisit
– palotasb
Nov 19 at 12:44
1
1
the problem is that you can't compare strings at compile time
– Stack Danny
Nov 19 at 12:59
the problem is that you can't compare strings at compile time
– Stack Danny
Nov 19 at 12:59
|
show 10 more comments
4 Answers
4
active
oldest
votes
up vote
8
down vote
accepted
You can use a mix of template function and if constexpr
(C++17):
template<typename T>
T valueOf() const {
if constexpr(std::is_same<T, bool>) return _boolValueOf();
else if constexpr(std::is_same<T, int>) return _intValueOf();
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf();
}
Requires passing the type, but then the signature could be:
template<typename T>
T valueOf(const T& d) const {
if constexpr(std::is_same<T, bool>) return _boolValueOf(d);
else if constexpr(std::is_same<T, int>) return _intValueOf(d);
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf(d);
}
4
Under the convenient assumption that the requested type is known at compile-time. In that case, there should not be differently named functions doing conceptually the same thing in the first place. There should be overloads for the supported types.
– LogicStuff
Nov 19 at 12:42
1
Yes, under this assumption, which makes sense because at some point you need to write something at compile time.
– Matthieu Brucher
Nov 19 at 12:44
1
does Is_same(T, bool) also works? I thought is_same<T, bool>...
– Zeta
Nov 19 at 12:50
1
@Zeta Oops, that's a typo, of course <>!
– Matthieu Brucher
Nov 19 at 12:52
1
You need then to have a SFINAE fucntion for each type with enable_if :/
– Matthieu Brucher
Nov 19 at 13:01
|
show 3 more comments
up vote
2
down vote
High-level and recomended solution is std::any
, std::variant
, std::optional
. Low-level, hackish dangerous, final solution is union
, void*,
static_cast
...
If you want neither, there is no more left to try. Do you finally want to do it in C++?
If are interested in the implementation of those high-level facilities, you can check the source code on open source implementations. But you will eventually find that those implementations device the low level constructs pointed above.
Whyoptional
? That's not at all helpful in this scenario.
– Nicol Bolas
Nov 19 at 15:35
In my interpretation, It has two return types: error or value. I have a nasty habit of generalization. Though not technically the case, I practically consider variant as a superset of optional and a subset of any.
– Red.Wave
Nov 19 at 16:21
add a comment |
up vote
1
down vote
First to have different return types you need to use a template to differentiate the functions. Then you can call var(true).valueOf<bool>()
for example. You will have to specify the template on every call so the compiler knows what function (and return type) to use. This can't be deduced on it's own.
Secondly the var.type is a string that can only be checked at runtime. So var(42).valueOf<bool>()
compiles just fine. You would have to check var.type against the template argument at runtime and throw an exception when the types don't match.
Not an ideal design.
add a comment |
up vote
0
down vote
For you valueOf
function, imo, user-defined conversion is also a choice:
operator std::string()
{
return primitive_value._char_pointer;
}
operator bool()
{
return primitive_value._bool;
}
operator int()
{
return primitive_value._int;
}
......
Then you can use like this:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1;
bool b = v2;
int c = v3;
std::cerr << static_cast<std::string>(v1) << 'n';
std::cerr << std::boolalpha << static_cast<bool>(v2) << 'n';
std::cerr << static_cast<int>(v3) << 'n';
If you still hope to use function, just add a operator()
:
var
operator()()
{
return *this;
}
Then you can:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1();
bool b = v2();
int c = v3();
But still a little ugly, right? Just add your valueOf
function:
var
valueOf()
{
return *this;
}
Then:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1.valueOf();
bool b = v2.valueOf();
int c = v3.valueOf();
But these solutions have many limitions. if constexpr
provided by Matthieu Brucher is more powerful. Just all about provide a idea here : ).
But please note, unlike if constexpr, the ways I provided is not really multiple types return, just user-defined conversion.
Of course, there are more solutions, like sfinae(use enable_if and is_same in return type), or tag dispatch, but both of them require template
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
You can use a mix of template function and if constexpr
(C++17):
template<typename T>
T valueOf() const {
if constexpr(std::is_same<T, bool>) return _boolValueOf();
else if constexpr(std::is_same<T, int>) return _intValueOf();
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf();
}
Requires passing the type, but then the signature could be:
template<typename T>
T valueOf(const T& d) const {
if constexpr(std::is_same<T, bool>) return _boolValueOf(d);
else if constexpr(std::is_same<T, int>) return _intValueOf(d);
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf(d);
}
4
Under the convenient assumption that the requested type is known at compile-time. In that case, there should not be differently named functions doing conceptually the same thing in the first place. There should be overloads for the supported types.
– LogicStuff
Nov 19 at 12:42
1
Yes, under this assumption, which makes sense because at some point you need to write something at compile time.
– Matthieu Brucher
Nov 19 at 12:44
1
does Is_same(T, bool) also works? I thought is_same<T, bool>...
– Zeta
Nov 19 at 12:50
1
@Zeta Oops, that's a typo, of course <>!
– Matthieu Brucher
Nov 19 at 12:52
1
You need then to have a SFINAE fucntion for each type with enable_if :/
– Matthieu Brucher
Nov 19 at 13:01
|
show 3 more comments
up vote
8
down vote
accepted
You can use a mix of template function and if constexpr
(C++17):
template<typename T>
T valueOf() const {
if constexpr(std::is_same<T, bool>) return _boolValueOf();
else if constexpr(std::is_same<T, int>) return _intValueOf();
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf();
}
Requires passing the type, but then the signature could be:
template<typename T>
T valueOf(const T& d) const {
if constexpr(std::is_same<T, bool>) return _boolValueOf(d);
else if constexpr(std::is_same<T, int>) return _intValueOf(d);
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf(d);
}
4
Under the convenient assumption that the requested type is known at compile-time. In that case, there should not be differently named functions doing conceptually the same thing in the first place. There should be overloads for the supported types.
– LogicStuff
Nov 19 at 12:42
1
Yes, under this assumption, which makes sense because at some point you need to write something at compile time.
– Matthieu Brucher
Nov 19 at 12:44
1
does Is_same(T, bool) also works? I thought is_same<T, bool>...
– Zeta
Nov 19 at 12:50
1
@Zeta Oops, that's a typo, of course <>!
– Matthieu Brucher
Nov 19 at 12:52
1
You need then to have a SFINAE fucntion for each type with enable_if :/
– Matthieu Brucher
Nov 19 at 13:01
|
show 3 more comments
up vote
8
down vote
accepted
up vote
8
down vote
accepted
You can use a mix of template function and if constexpr
(C++17):
template<typename T>
T valueOf() const {
if constexpr(std::is_same<T, bool>) return _boolValueOf();
else if constexpr(std::is_same<T, int>) return _intValueOf();
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf();
}
Requires passing the type, but then the signature could be:
template<typename T>
T valueOf(const T& d) const {
if constexpr(std::is_same<T, bool>) return _boolValueOf(d);
else if constexpr(std::is_same<T, int>) return _intValueOf(d);
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf(d);
}
You can use a mix of template function and if constexpr
(C++17):
template<typename T>
T valueOf() const {
if constexpr(std::is_same<T, bool>) return _boolValueOf();
else if constexpr(std::is_same<T, int>) return _intValueOf();
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf();
}
Requires passing the type, but then the signature could be:
template<typename T>
T valueOf(const T& d) const {
if constexpr(std::is_same<T, bool>) return _boolValueOf(d);
else if constexpr(std::is_same<T, int>) return _intValueOf(d);
else if constexpr(std::is_same<T, std::string>) return _std_stringValueOf(d);
}
edited Nov 19 at 13:37
Lapys
396313
396313
answered Nov 19 at 12:36
Matthieu Brucher
7,48011431
7,48011431
4
Under the convenient assumption that the requested type is known at compile-time. In that case, there should not be differently named functions doing conceptually the same thing in the first place. There should be overloads for the supported types.
– LogicStuff
Nov 19 at 12:42
1
Yes, under this assumption, which makes sense because at some point you need to write something at compile time.
– Matthieu Brucher
Nov 19 at 12:44
1
does Is_same(T, bool) also works? I thought is_same<T, bool>...
– Zeta
Nov 19 at 12:50
1
@Zeta Oops, that's a typo, of course <>!
– Matthieu Brucher
Nov 19 at 12:52
1
You need then to have a SFINAE fucntion for each type with enable_if :/
– Matthieu Brucher
Nov 19 at 13:01
|
show 3 more comments
4
Under the convenient assumption that the requested type is known at compile-time. In that case, there should not be differently named functions doing conceptually the same thing in the first place. There should be overloads for the supported types.
– LogicStuff
Nov 19 at 12:42
1
Yes, under this assumption, which makes sense because at some point you need to write something at compile time.
– Matthieu Brucher
Nov 19 at 12:44
1
does Is_same(T, bool) also works? I thought is_same<T, bool>...
– Zeta
Nov 19 at 12:50
1
@Zeta Oops, that's a typo, of course <>!
– Matthieu Brucher
Nov 19 at 12:52
1
You need then to have a SFINAE fucntion for each type with enable_if :/
– Matthieu Brucher
Nov 19 at 13:01
4
4
Under the convenient assumption that the requested type is known at compile-time. In that case, there should not be differently named functions doing conceptually the same thing in the first place. There should be overloads for the supported types.
– LogicStuff
Nov 19 at 12:42
Under the convenient assumption that the requested type is known at compile-time. In that case, there should not be differently named functions doing conceptually the same thing in the first place. There should be overloads for the supported types.
– LogicStuff
Nov 19 at 12:42
1
1
Yes, under this assumption, which makes sense because at some point you need to write something at compile time.
– Matthieu Brucher
Nov 19 at 12:44
Yes, under this assumption, which makes sense because at some point you need to write something at compile time.
– Matthieu Brucher
Nov 19 at 12:44
1
1
does Is_same(T, bool) also works? I thought is_same<T, bool>...
– Zeta
Nov 19 at 12:50
does Is_same(T, bool) also works? I thought is_same<T, bool>...
– Zeta
Nov 19 at 12:50
1
1
@Zeta Oops, that's a typo, of course <>!
– Matthieu Brucher
Nov 19 at 12:52
@Zeta Oops, that's a typo, of course <>!
– Matthieu Brucher
Nov 19 at 12:52
1
1
You need then to have a SFINAE fucntion for each type with enable_if :/
– Matthieu Brucher
Nov 19 at 13:01
You need then to have a SFINAE fucntion for each type with enable_if :/
– Matthieu Brucher
Nov 19 at 13:01
|
show 3 more comments
up vote
2
down vote
High-level and recomended solution is std::any
, std::variant
, std::optional
. Low-level, hackish dangerous, final solution is union
, void*,
static_cast
...
If you want neither, there is no more left to try. Do you finally want to do it in C++?
If are interested in the implementation of those high-level facilities, you can check the source code on open source implementations. But you will eventually find that those implementations device the low level constructs pointed above.
Whyoptional
? That's not at all helpful in this scenario.
– Nicol Bolas
Nov 19 at 15:35
In my interpretation, It has two return types: error or value. I have a nasty habit of generalization. Though not technically the case, I practically consider variant as a superset of optional and a subset of any.
– Red.Wave
Nov 19 at 16:21
add a comment |
up vote
2
down vote
High-level and recomended solution is std::any
, std::variant
, std::optional
. Low-level, hackish dangerous, final solution is union
, void*,
static_cast
...
If you want neither, there is no more left to try. Do you finally want to do it in C++?
If are interested in the implementation of those high-level facilities, you can check the source code on open source implementations. But you will eventually find that those implementations device the low level constructs pointed above.
Whyoptional
? That's not at all helpful in this scenario.
– Nicol Bolas
Nov 19 at 15:35
In my interpretation, It has two return types: error or value. I have a nasty habit of generalization. Though not technically the case, I practically consider variant as a superset of optional and a subset of any.
– Red.Wave
Nov 19 at 16:21
add a comment |
up vote
2
down vote
up vote
2
down vote
High-level and recomended solution is std::any
, std::variant
, std::optional
. Low-level, hackish dangerous, final solution is union
, void*,
static_cast
...
If you want neither, there is no more left to try. Do you finally want to do it in C++?
If are interested in the implementation of those high-level facilities, you can check the source code on open source implementations. But you will eventually find that those implementations device the low level constructs pointed above.
High-level and recomended solution is std::any
, std::variant
, std::optional
. Low-level, hackish dangerous, final solution is union
, void*,
static_cast
...
If you want neither, there is no more left to try. Do you finally want to do it in C++?
If are interested in the implementation of those high-level facilities, you can check the source code on open source implementations. But you will eventually find that those implementations device the low level constructs pointed above.
answered Nov 19 at 14:21
Red.Wave
72337
72337
Whyoptional
? That's not at all helpful in this scenario.
– Nicol Bolas
Nov 19 at 15:35
In my interpretation, It has two return types: error or value. I have a nasty habit of generalization. Though not technically the case, I practically consider variant as a superset of optional and a subset of any.
– Red.Wave
Nov 19 at 16:21
add a comment |
Whyoptional
? That's not at all helpful in this scenario.
– Nicol Bolas
Nov 19 at 15:35
In my interpretation, It has two return types: error or value. I have a nasty habit of generalization. Though not technically the case, I practically consider variant as a superset of optional and a subset of any.
– Red.Wave
Nov 19 at 16:21
Why
optional
? That's not at all helpful in this scenario.– Nicol Bolas
Nov 19 at 15:35
Why
optional
? That's not at all helpful in this scenario.– Nicol Bolas
Nov 19 at 15:35
In my interpretation, It has two return types: error or value. I have a nasty habit of generalization. Though not technically the case, I practically consider variant as a superset of optional and a subset of any.
– Red.Wave
Nov 19 at 16:21
In my interpretation, It has two return types: error or value. I have a nasty habit of generalization. Though not technically the case, I practically consider variant as a superset of optional and a subset of any.
– Red.Wave
Nov 19 at 16:21
add a comment |
up vote
1
down vote
First to have different return types you need to use a template to differentiate the functions. Then you can call var(true).valueOf<bool>()
for example. You will have to specify the template on every call so the compiler knows what function (and return type) to use. This can't be deduced on it's own.
Secondly the var.type is a string that can only be checked at runtime. So var(42).valueOf<bool>()
compiles just fine. You would have to check var.type against the template argument at runtime and throw an exception when the types don't match.
Not an ideal design.
add a comment |
up vote
1
down vote
First to have different return types you need to use a template to differentiate the functions. Then you can call var(true).valueOf<bool>()
for example. You will have to specify the template on every call so the compiler knows what function (and return type) to use. This can't be deduced on it's own.
Secondly the var.type is a string that can only be checked at runtime. So var(42).valueOf<bool>()
compiles just fine. You would have to check var.type against the template argument at runtime and throw an exception when the types don't match.
Not an ideal design.
add a comment |
up vote
1
down vote
up vote
1
down vote
First to have different return types you need to use a template to differentiate the functions. Then you can call var(true).valueOf<bool>()
for example. You will have to specify the template on every call so the compiler knows what function (and return type) to use. This can't be deduced on it's own.
Secondly the var.type is a string that can only be checked at runtime. So var(42).valueOf<bool>()
compiles just fine. You would have to check var.type against the template argument at runtime and throw an exception when the types don't match.
Not an ideal design.
First to have different return types you need to use a template to differentiate the functions. Then you can call var(true).valueOf<bool>()
for example. You will have to specify the template on every call so the compiler knows what function (and return type) to use. This can't be deduced on it's own.
Secondly the var.type is a string that can only be checked at runtime. So var(42).valueOf<bool>()
compiles just fine. You would have to check var.type against the template argument at runtime and throw an exception when the types don't match.
Not an ideal design.
answered Nov 19 at 14:43
Goswin von Brederlow
2,527724
2,527724
add a comment |
add a comment |
up vote
0
down vote
For you valueOf
function, imo, user-defined conversion is also a choice:
operator std::string()
{
return primitive_value._char_pointer;
}
operator bool()
{
return primitive_value._bool;
}
operator int()
{
return primitive_value._int;
}
......
Then you can use like this:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1;
bool b = v2;
int c = v3;
std::cerr << static_cast<std::string>(v1) << 'n';
std::cerr << std::boolalpha << static_cast<bool>(v2) << 'n';
std::cerr << static_cast<int>(v3) << 'n';
If you still hope to use function, just add a operator()
:
var
operator()()
{
return *this;
}
Then you can:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1();
bool b = v2();
int c = v3();
But still a little ugly, right? Just add your valueOf
function:
var
valueOf()
{
return *this;
}
Then:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1.valueOf();
bool b = v2.valueOf();
int c = v3.valueOf();
But these solutions have many limitions. if constexpr
provided by Matthieu Brucher is more powerful. Just all about provide a idea here : ).
But please note, unlike if constexpr, the ways I provided is not really multiple types return, just user-defined conversion.
Of course, there are more solutions, like sfinae(use enable_if and is_same in return type), or tag dispatch, but both of them require template
add a comment |
up vote
0
down vote
For you valueOf
function, imo, user-defined conversion is also a choice:
operator std::string()
{
return primitive_value._char_pointer;
}
operator bool()
{
return primitive_value._bool;
}
operator int()
{
return primitive_value._int;
}
......
Then you can use like this:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1;
bool b = v2;
int c = v3;
std::cerr << static_cast<std::string>(v1) << 'n';
std::cerr << std::boolalpha << static_cast<bool>(v2) << 'n';
std::cerr << static_cast<int>(v3) << 'n';
If you still hope to use function, just add a operator()
:
var
operator()()
{
return *this;
}
Then you can:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1();
bool b = v2();
int c = v3();
But still a little ugly, right? Just add your valueOf
function:
var
valueOf()
{
return *this;
}
Then:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1.valueOf();
bool b = v2.valueOf();
int c = v3.valueOf();
But these solutions have many limitions. if constexpr
provided by Matthieu Brucher is more powerful. Just all about provide a idea here : ).
But please note, unlike if constexpr, the ways I provided is not really multiple types return, just user-defined conversion.
Of course, there are more solutions, like sfinae(use enable_if and is_same in return type), or tag dispatch, but both of them require template
add a comment |
up vote
0
down vote
up vote
0
down vote
For you valueOf
function, imo, user-defined conversion is also a choice:
operator std::string()
{
return primitive_value._char_pointer;
}
operator bool()
{
return primitive_value._bool;
}
operator int()
{
return primitive_value._int;
}
......
Then you can use like this:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1;
bool b = v2;
int c = v3;
std::cerr << static_cast<std::string>(v1) << 'n';
std::cerr << std::boolalpha << static_cast<bool>(v2) << 'n';
std::cerr << static_cast<int>(v3) << 'n';
If you still hope to use function, just add a operator()
:
var
operator()()
{
return *this;
}
Then you can:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1();
bool b = v2();
int c = v3();
But still a little ugly, right? Just add your valueOf
function:
var
valueOf()
{
return *this;
}
Then:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1.valueOf();
bool b = v2.valueOf();
int c = v3.valueOf();
But these solutions have many limitions. if constexpr
provided by Matthieu Brucher is more powerful. Just all about provide a idea here : ).
But please note, unlike if constexpr, the ways I provided is not really multiple types return, just user-defined conversion.
Of course, there are more solutions, like sfinae(use enable_if and is_same in return type), or tag dispatch, but both of them require template
For you valueOf
function, imo, user-defined conversion is also a choice:
operator std::string()
{
return primitive_value._char_pointer;
}
operator bool()
{
return primitive_value._bool;
}
operator int()
{
return primitive_value._int;
}
......
Then you can use like this:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1;
bool b = v2;
int c = v3;
std::cerr << static_cast<std::string>(v1) << 'n';
std::cerr << std::boolalpha << static_cast<bool>(v2) << 'n';
std::cerr << static_cast<int>(v3) << 'n';
If you still hope to use function, just add a operator()
:
var
operator()()
{
return *this;
}
Then you can:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1();
bool b = v2();
int c = v3();
But still a little ugly, right? Just add your valueOf
function:
var
valueOf()
{
return *this;
}
Then:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1.valueOf();
bool b = v2.valueOf();
int c = v3.valueOf();
But these solutions have many limitions. if constexpr
provided by Matthieu Brucher is more powerful. Just all about provide a idea here : ).
But please note, unlike if constexpr, the ways I provided is not really multiple types return, just user-defined conversion.
Of course, there are more solutions, like sfinae(use enable_if and is_same in return type), or tag dispatch, but both of them require template
edited Nov 19 at 14:11
answered Nov 19 at 13:58
陳 力
1,3241622
1,3241622
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53374738%2fmultiple-return-type-from-function-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
8
std::variant
just does what you are asking. you could implement it yourself if you really want– M.M
Nov 19 at 12:34
6
The example code you show looks like a bad design. And why can't you use e.g.
std::any
orstd::variant
? How about templates (possibly with specialization)?– Some programmer dude
Nov 19 at 12:34
2
how would you call the function? Lets say you make it return different types, then also the caller has to be able to handle different types. Whatever you do it will be either complicated or broken or both. I agree that this is probably not the best design
– user463035818
Nov 19 at 12:37
2
See this: arne-mertz.de/2018/05/modern-c-features-stdvariant-and-stdvisit
– palotasb
Nov 19 at 12:44
1
the problem is that you can't compare strings at compile time
– Stack Danny
Nov 19 at 12:59