簡體   English   中英

返回具有不同模板參數值的不同類型(但相同類型)

[英]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-constexprdecltype(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM