簡體   English   中英

在函數模板特化中覆蓋返回類型

[英]Overriding return type in function template specialization

我想專門化一個函數模板,以便返回類型根據模板參數的類型而變化。

class ReturnTypeSpecialization
{
public:
    template<typename T>
    T Item();
};

// Normally just return the template type
template<typename T>
T ReturnTypeSpecialization::Item() { ... }

// When a float is specified, return an int
// This doesn't work:
template<float>
int ReturnTypeSpecialization::Item() { ... }

這可能嗎? 我不能使用 C++11。

由於特化必須與返回類型的基本模板一致,您可以通過添加“返回類型特征”來實現,您可以特化並從中繪制真正的返回類型的結構:

// in the normal case, just the identity
template<class T>
struct item_return{ typedef T type; };

template<class T>
typename item_return<T>::type item();

template<>
struct item_return<float>{ typedef int type; };
template<>
int item<float>();

活生生的例子。

請注意,您可能希望遵循以下規則,因此您只需更新item_return專業化中的 return-type。

template<>
item_return<float>::type foo<float>(){ ... }
// note: No `typename` needed, because `float` is not a dependent type

在工作類中完成所有特化,並使用一個簡單的函數作為隱式特化的包裝器。

#include <iostream>
using std::cout;

// worker class -- return a reference to the given value
template< typename V > struct worker
   {
   typedef V const & type;
   static type get( V const & v ) { return v; }
   };

// worker class specialization -- convert 'unsigned char' to 'int'
template<> struct worker<unsigned char>
   {
   typedef int type;
   static type get( unsigned char const & v ) { return v; }
   };

// mapper function
template< typename V > typename worker<V>::type mapper( V const & v )
   {
   return worker<V>::get(v);
   }

int main()
   {
   char a='A';
   unsigned char b='B';
   cout << "a=" << mapper(a) << ", b=" << mapper(b) << "\n";
   }

在這個例子中, unsigned char導致它被轉換為一個int以便cout將它顯示為一個數字而不是一個字符,生成以下輸出......

a=A, b=66

也許您可以使用以下技巧。 鑒於這些簡單的類型特征:

template<bool b, typename T, typename U>
struct conditional { typedef T type; };

template<typename T, typename U>
struct conditional<false, T, U> { typedef U type; };

template<typename T, typename U>
struct is_same { static const bool value = false; };

template<typename T>
struct is_same<T, T> { static const bool value = true; };

您可以按如下方式編寫您的類和專門的成員函數:

class ReturnTypeSpecialization
{
public:
    template<typename T>
    typename conditional<is_same<T, float>::value, int, T>::type 
    Item();
};

// Normally just return the template type
template<typename T>
typename conditional<is_same<T, float>::value, int, T>::type
ReturnTypeSpecialization::Item() { return T(); }

// When a float is specified, return an int
template<>
int ReturnTypeSpecialization::Item<float>() { return 1.0f; }

簡單的測試程序(僅使用 C++11 進行驗證):

int main()
{
    ReturnTypeSpecialization obj;
    static_assert(std::is_same<decltype(obj.Item<bool>()), bool>::value, "!");
    static_assert(std::is_same<decltype(obj.Item<float>()), int>::value, "!");
}

這是一個活生生的例子

您可以像這樣進行模板專業化:

template<typename T>
T item() {
    return T();
}

template<>
float item<float>() {
    return 1.0f;
}

嗨,我嘗試使用模板專業化來返回基元的參數值以及 std::string 數據,同時我遇到了很多未解決的外部重新定義錯誤。 因此,如果有人遇到這樣的情況,他/她可以在想要返回包括字符串在內的不同數據類型時使用如下所示的內容,注意:模板函數都必須是頭文件 (*.h) 的一部分...所以我們在這里使用模板特化字符串數據類型......在類內部作為內聯成員,我們必須使用模板特化方法,並且在同一個文件中我們也可以定義模板。

class ConfigFileParser
{
public:
    bool ParseConfigFile(const std::string& file_name);
    template <typename T>
    T GetParameterValue(const std::string key);
    template <>
    std::string GetParameterValue<std::string>(const std::string key)
    {
        std::string param_val = "";
        //do logical operation here... 
        return param_val;
    }
private:
    // private functions...

    // private data...
};

template <typename T>
T ConfigFileParser::GetParameterValue(const std::string key)
{
    T param_val = 0;
    std::stringstream ss;
    std::string val_str;
    // do some operation here...
    ss << val_str.c_str();
    ss >> param_val;

    return param_val;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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