[英]Multiple return type from function - C++
是否有任何方法(傳統方法或否方法)可從函數中在多個指定的返回類型之間進行選擇。 例如:
/* 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;
}
};
我在這里看到一個類似問題的參考,建議使用void*
指針或union
,但是我還沒有完全理解它們是如何工作的。
不允許使用任何容器類型(例如std::any
, std::optional
, std::variant
),因為我想知道是否還有替代方法。
補充一點,這一切都是出於好奇 。 目前,我正在搜索optional
和variant
頭文件,以了解我所要求的功能是如何實現的,但到目前為止還算不上成功。
我希望這里的平台可以為這個潛在問題提供實用的解決方案。
您可以混合使用模板函數和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();
}
需要傳遞類型,但是簽名可以是:
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);
}
高級推薦的解決方案是std::any
, std::variant
, std::optional
。 低級,駭人聽聞的危險,最終解決方案是union
, void*,
static_cast
……如果您都不想要,那就static_cast
嘗試了。 您最終想用C ++做到嗎?
如果對這些高級工具的實現感興趣,則可以檢查開源實現的源代碼。 但是,您最終會發現,這些實現使用了上面指出的底層構造。
首先要具有不同的返回類型,您需要使用模板來區分功能。 然后,您可以例如調用var(true).valueOf<bool>()
。 您將必須在每次調用時指定模板,以便編譯器知道要使用的函數(和返回類型)。 不能單憑此推論。
其次,var.type是只能在運行時檢查的字符串。 因此var(42).valueOf<bool>()
編譯就很好。 您將必須在運行時對照模板參數檢查var.type,並在類型不匹配時引發異常。
不是理想的設計。
對於您的valueOf
函數,imo也是用戶定義的轉換 :
operator std::string()
{
return primitive_value._char_pointer;
}
operator bool()
{
return primitive_value._bool;
}
operator int()
{
return primitive_value._int;
}
......
然后,您可以像這樣使用:
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';
如果仍然希望使用函數,只需添加一個operator()
:
var
operator()()
{
return *this;
}
那么你也能:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1();
bool b = v2();
int c = v3();
但是還是有點難看吧? 只需添加您的valueOf
函數:
var
valueOf()
{
return *this;
}
然后:
var v1("hello");
var v2(true);
var v3(10);
std::string a = v1.valueOf();
bool b = v2.valueOf();
int c = v3.valueOf();
但是這些解決方案有很多局限性。 if constexpr
Matthieu Brucher提供的if constexpr
更強大。 只是在這里提供一個想法:)。 但是請注意,與constexpr不同,我提供的方法實際上不是多種類型的return ,而是用戶定義的轉換。
當然,還有更多解決方案,例如sfinae(在返回類型中使用enable_if和is_same)或標簽分發,但它們都需要模板
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.