[英]class template specialization with template
我有一個類模板name
來檢測類型名稱。 它適用於簡單類型,例如int
, float
。 但是,對於某些模板類型,例如std:pair
,當我嘗試定義其靜態成員變量時,編譯器(VS2013)在此行報告錯誤。
#include <cassert>
#include <memory>
using namespace std;
template<class T> struct name{ static const char* value; };
template<class T> const char* name<T>::value = "unknown";
template<> const char* name<int>::value = "int";
template<> const char* name<float>::value = "float";
template<class T1, class T2> const char* name<pair<T1, T2> >::value = "pair"; //compilation error
void main()
{
assert(name<int>::value == "int");
assert(name<float>::value == "float");
assert(name<double>::value == "unknown");
assert((name<pair<int, char> >::value) == "pair");
}
如果我用以下四行替換該行,程序將按預期運行。
template<class T1, class T2> struct name < pair<T1, T2> > {
static const char* value;
};
template<class T1, class T2> const char* name<pair<T1, T2> >::value = "pair";
但是由於一些重復的代碼,這種方法看起來很丑陋。 有什么辦法走走嗎?
更新以解決一些明顯的符合標准的問題。
首先: template<>
必須引入任何顯式的專業化。 嘗試保持符合標准。
但是由於一些重復的代碼,這種方法看起來很丑陋。 有什么辦法走走嗎?
否。不是顯式專業化的成員定義中的參數和參數列表必須與主模板或其部分專業化之一的列表匹配,並且它與與其列表匹配的模板成員相對應。 [temp.class.spec.mfunc]:
類模板部分專業化成員的模板參數列表應與類模板部分專業化的模板參數列表匹配。 類模板部分專業化成員的模板參數列表應與類模板部分專業化的模板參數列表匹配。
因此,您必須部分專門化模板。 您可以為此使用宏:
#define REM_PAR(...) __VA_ARGS__
#define PART_SPEC(string, params, ...) \
template<REM_PAR params> struct name <__VA_ARGS__ > \
{ static const char* value; }; \
\
template<REM_PAR params> const char* name<__VA_ARGS__>::value = string;
PART_SPEC("pair", (class T, class U), pair<T,U>)
首先,作為參考,這是您的偽代碼在C ++中的外觀:
#include <cassert> // for assert
#include <cstring> // for std::strcmp
#include <utility> // for std::pair
template <class T> struct name
{ static const char * const value; };
template <class T>
const char * const name<T>::value = "unknown";
template <> // "template <>" for specialization
const char * const name<int>::value = "int";
template <> // "template <>" for specialization
const char * const name<float>::value = "float";
// template <class T1, class T2> // Error here (partial
// const char * const name<std::pair<T1, T2>>::value = "pair"; // spec'n not allowed)
int main() // return type int
{
assert(std::strcmp(name<int>::value, "int") == 0); // strcmp!
assert(std::strcmp(name<float>::value,"float") == 0);
assert(std::strcmp(name<double>::value, "unknown") == 0);
assert(std::strcmp(name<std::pair<int, char>>::value,"pair") == 0);
}
現在,您可以通過這種方式進行部分專業化工作:專門化整個模板。
template <class T1, class T2> struct name<std::pair<T1, T2>>
{ static const char * const value; };
template <class T1, class T2>
const char * const name<std::pair<T1, T2>>::value = "pair";
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.