[英]Return different types with different template parameter value (but same type)
我想要做的是定義3個這樣的函數:
template<int t = 0> int test() { return 8; }
template<int t = 1> float test() { return 8.8; }
template<int t = 2> std::string test() { return "8.9"; }
int main()
{
int a = test<0>();
float b = test<1>();
std::string c = test<2>();
return 0;
}
它們使用相同類型的模板參數,但返回不同的類型。
我相信必須有一些方法可以做到這一點(比如std::get<>()
就可以了),但我找不到怎么做。
它看起來像你在功能模板專業化之后。 需要為每個呼叫提供不同的實現符合要求。 然而,有一點需要注意,即專業化可能不會改變專用主模板的簽名,只會改變實現。 這意味着我們不能這樣做
template<int t> int test(); // Primary
template<> int test<0>() { return 8; } // OK, signature matches
template<> float test<1>() { return 8.8; } // ERROR
但我們還沒有敬酒。 專業化的簽名必須與主要為特定參數獲得的簽名相匹配。 因此,如果我們使返回類型依賴於模板參數,並解析為正確的類型,我們可以很好地定義我們的特化。
template<int t> auto test() -> /* Magic involving t that resolves to int, float, string */;
template<> int test<0>() { return 8; }
template<> float test<1>() { return 8.8; }
template<> std::string test<2>() { return "8.9"; }
這樣的事情存在嗎? 是的,你暗示了它。 我們可以使用std::tuple
。 它有一個std::tuple_element
實用程序,可以將整數映射到一個類型序列(元組的元素)。 有了一個小幫手,我們可以構建我們的代碼,以您希望的方式工作:
using types = std::tuple<int, float, std::string>;
template<int t> auto test() -> std::tuple_element_t<t, types>;
template<> int test<0>() { return 8; }
template<> float test<1>() { return 8.8; }
template<> std::string test<2>() { return "8.9"; }
現在,每個專業化都會匹配主要最終的簽名。 所以我們得到了編譯器的批准。
@StoryTeller和@ formerlyknownas_463035818提供了一個解釋良好的模板專業化方法。 或者,可以使用if-constexpr和c ++ 17中的decltype(auto)
返回將三個函數組合成一個函數。
#include <iostream>
#include <string>
#include <cstring>
using namespace std::literals;
template<int t>
constexpr decltype(auto) test() noexcept
{
if constexpr (t == 0) return 8;
else if constexpr (t == 1) return 8.8f;
else if constexpr (t == 2) return "8.9"s;
}
( 見在線直播 )
您聲明了相同的模板3次,而您實際上想要專業化。 據我所知,你不能直接專注於返回類型(*)。 但是,沒有什么是通過額外的間接層無法解決的。 您可以按照以下方式執行以下操作:
#include <string>
template <int> struct return_type_tag {};
template <> struct return_type_tag<0> { using type = int; };
template <> struct return_type_tag<1> { using type = float; };
template <> struct return_type_tag<2> { using type = std::string; };
template <int x> typename return_type_tag<x>::type test();
template<> int test<0>() { return 8; }
template<> float test<1>() { return 8.8; }
template<> std::string test<2>() { return "8.9"; }
int main()
{
int a = test<0>();
float b = test<1>();
std::string c = test<2>();
return 0;
}
(*)實際上你可以通過一個小技巧看到這個答案 。 我的方法的唯一好處是它已經在pre-c ++ 11中運行了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.