Reputation: 421
Trying to write a function that determines its own return type according to some preprocessor directives. But i am not sure if this is possible in C++.
type ConvertStrIfNecessary(){
std::str mystr="abcdefghif";
#ifdef MYCONDITION
return mystr.c_str();
#else
return mystr;
#endif
}
Upvotes: 1
Views: 91
Reputation: 5241
If you want to do everything with preprocessor commands you could define your own string type
#ifdef MYCONDITION
#define STRING_TYPE const char*
#else
#define STRING_TYPE std::string
#end
Then your function would be
STRING_TYPE ConvertStrIfNecessary(){
std::string mystr="abcdefghif";
#ifdef MYCONDITION
return mystr.c_str();
#else
return mystr;
#endif
}
But, again, be careful with returning .c_str()
. However, apart from the use of std::string
, this is very much the C way of doing things, prefer a solution like auto
if your using C++ (see Zeta's solution).
Upvotes: 1
Reputation: 105876
It depends on your compiler and whether it supports N3638 (g++ since 4.9):
/*
vvvv "auto" is enough */
auto ConvertStrIfNecessary(){
std::string mystr="abcdefghif";
#ifdef MYCONDITION
return mystr.c_str();
#else
return mystr;
#endif
}
You need to enable C++14 with -std=c++14
in GCC. Keep in mind that C++14 support is still experimental. Note that this only works if all return
s in your function return values of the same type. Since there's only one return
after preprocessing it's fine in this case.
Your users could then use auto
again:
auto theValue = ConvertStrIfNecessary();
That being said, your code yields undefined behaviour if you return mystr.c_str()
, since the pointer returned by c_str()
is invalidated when mystr
goes out of scope.
Even worse, const char*
and std::string
have different semantics, and the code will most likely not compile later since some client used theValue
as char*
, where someone else used it as std::string
.
If you really want different types, you could instead provide a common interface type:
#ifdef MYCONDITION
using stringlike_t = const char *;
#else
using stringlike_t = std::string;
#endif
That gives you control on the "safe" methods a user can use.
Upvotes: 4