簡體   English   中英

非專業化的C ++模板參數

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

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