5

我想寫如下:我應該做什麼而不是功能模板的部分專業化?

template <typename S, typename T> void foo() { 
    /* code for the general case */ 
} 

template <typename T> void foo<MySType,T>() { 
    /* partially specialized code - for any kind of T, but when S is MySType */ 
} 

,或者在其他情況下,執行以下操作:

template <typename S, typename T> void bar(const S& a, const T& b) { 
    /* code for the general case */ 
} 

template <typename T> void bar<MySType,T>(const MySType& a, const T& b) { 
    /* partially specialized code - for any kind of T, but when S is MySType */ 
} 

C++(11)不會讓我做這件事。現在

,我讀this question and its answers;假設我購買了爲什麼我們沒有部分模板專業化的解釋(或者假設我生活在現實中並且實際上想要編寫代碼)。那麼,什麼我呢,而不是?

我實在不好意思在一個類中,除非那是絕對我的最後的手段包裝這些功能。

+0

老實說,我潛入C++ 11和C++一般的越多,我越覺得「模板特」是正在發生的事情的可怕資格。沒有「模板專業化」這樣的東西 – user2485710

+0

@ user2485710:對不起,我不明白......你能詳細說明嗎?或者鏈接到你認爲更長的地方? – einpoklum

+1

不僅模板專業化是一件事情,它是一個圖靈完整的機器。不過,它可以讓你生氣。 – Potatoswatter

回答

3

另一種方法是使用一個輔助類模板,在那裏你可以部分特化,並使用它不需要包裝函數隱藏它被部分專業本身:

#include <iostream> 

template<typename S, typename T> 
struct foo_helper { 
    void foo() { 
     std::cout << "general func" << std::endl;   
    } 
}; 

struct MyType {}; 

template <typename T> 
struct foo_helper <MyType,T> { 
    void foo() { 
     std::cout << "partially specialized code - for any kind of T, but when S is MyType" << std::endl; 
    } 
}; 

template<typename S, typename T> 
void foo() { 
    foo_helper<S, T>().foo(); 
} 

int main() { 
    foo<int, int>(); 
    foo<int, double>(); 
    foo<MyType, long>(); 
} 

這是有效的C++ 98/03也是如此。

+0

我可以以某種方式自動化/大小化助手結構的使用嗎? – einpoklum

5

超載!在任何專業化方面,超載都是優越的。重載解決方案的一部分是挑選最專業的過載。只要將「專業化」聲明爲重載,並且如果部分專業化就會有效。

避免明確的模板參數,雖然。您可以使用標籤分派。

template< typename t > 
struct tag {}; 

template <typename S, typename T> foo(tag<S>, tag<T>) { 
    /* code for the general case */ 
} 

template <typename T> foo(tag<MyType>, tag<T>) { 
    /* partially specialized code - for any kind of T, but when S is MyType */ 
} 

由於標籤是空的,按值傳遞,他們的貢獻,函數調用的開銷可以被編譯器消除。

+0

OP的例子構造得很差(缺少返回類型等),但帶來了一個有趣的轉折。主要是,你如何重載有*無參數*的東西? – WhozCraig

+0

@WhozCraig查看更新 – Potatoswatter

+0

+1我準備發佈一個tag-dispatch = P – WhozCraig

2

你可能部分專門的輔助結構:

#include <iostream> 

namespace Detail { 
    template <typename S, typename T> 
    struct Foo { 
     static void apply() { 
      std::cout << "general case\n"; 
     } 
    }; 
    template <typename T> 
    struct Foo<int, T> { 
     static void apply() { 
      std::cout << "specialized code\n"; 
     } 
    }; 
} 

template <typename S, typename T> 
void foo() { 
    Detail::Foo<S, T>::apply(); 
} 

int main() 
{ 
    foo<double, double>(); 
    foo<int, double>(); 
    return 0; 
} 
+0

這可以以某種方式自動/精簡,以便我不必總是明確寫入命名空間,結構等等? – einpoklum