[英]Un-specializing C++ template parameter
基本上我想做的如下。 假設我們有一個模板成員函數foo :
template <typename T>
T SomeClass::foo();
以及用戶以某種方式通過map <string,int>作為模板參數:
foo<map<string, int>>();
我要在這里做的是,在定義函數foo時 ,獲取內部類型, 字符串和整數 。 我嘗試了許多猜測工作以使該論據非專業化,但無濟於事。
template <map<typename K, typename V>>
map<K, V> SomeClass::foo(); // absolutely illegal
我考慮過使用部分專業化,但是由於foo是類成員函數而無法使用。
如果您想以一種通用的方式從模板中獲取內部類型,則可以使用顯式專門化:
template <typename T>
struct unpack;
template <template <typename...> class C, typename A, typename B>
struct unpack<C<A, B>>
{
using first = A;
using second = B;
};
用法:
static_assert(std::is_same_v<string,
typename unpack<map<string, int>>::first
>);
static_assert(std::is_same_v<int,
typename unpack<map<string, int>>::second
>);
如果只在調用函數時關心這樣做,則可以將函數設為模板:
template <typename K, typename V>
void foo(std::map<K, V>);
袖口:
template< class T >
struct Foo
{
static auto impl() -> T;
};
template< class K, class V >
struct Foo< map< K, V > >
{
static auto impl() -> map< K, V >;
};
template< class T >
auto foo()
-> T
{ return Foo<T>::impl(); }
這是另一個可能的解決方案。 方法foo調度到foo_detail方法,該方法將指向T的指針作為參數。 該參數未在foo_detail中使用。 相反,該參數允許重載解決方案選擇調用哪個foo_detail。
由於未使用參數,該解決方案有些笨拙。 幸運的是,這可以隱藏在SomeClass的私有部分中,這樣SomeClass的用戶不必知道它。
#include <map>
#include <iostream>
#include <string>
#include <typeinfo>
using std::map;
using std::cout;
using std::endl;
using std::string;
class SomeClass
{
public:
template <typename T>
T foo()
{
return foo_detail((T *)0);
}
private:
template<typename T>
T foo_detail(T *)
{
cout << "foo called with type " << typeid(T).name() << endl;
return T();
}
template <typename K, typename V>
map<K, V> foo_detail(map<K, V> *)
{
cout << "foo map specialization called with types "
<< typeid(K).name() << ' ' << typeid(V).name() << endl;
return map<K,V>();
}
};
int main()
{
SomeClass s;
s.foo<double>();
s.foo<map<int, string> >();
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.