[英]C++: Partially specializing template's type parameter as another template class's member-type
我有一個模板結構SFoo
,其中包含成員struct SZug
:
template <typename tTYPE>
struct SFoo
{
struct SZug {};
};
我還有另一個帶有類型參數的struct SBar
:
template <typename tTYPE>
struct SBar
{ /* stuff */ };
我想專門SBar
使用SZug
的類型參數,如下所示:
template <typename tTYPE>
struct SBar<typename SFoo<tTYPE>::SZug>
{ /* different stuff */ };
這不會編譯-LLVM輸出:
不可推導模板參數'tTYPE'
盡管編譯器可以根據需要輕松推斷出這種情況,但我猜測這只是C ++規范需要專門涵蓋這種情況。
有什么辦法可以做到這一點?
(注:我目前工作圍繞它通過移動SZug
之外SFoo
和使用using
聲明,但它是丑陋的。)
我不確定我是否完全了解您想要做什么,但是您可以嘗試以下操作(它只需要向SZug
添加特定屬性:
template <typename tTYPE>
struct SFoo {
struct SZug {
// Add this to be able to obtain SFoo<T> from SFoo<T>::SZug
using type = tTYPE;
};
};
然后是一個小模板,用於檢查類型是否為SFoo<T>::SZug
:
template <typename tTYPE, typename Enabler = void>
struct is_SZug: public std::false_type { };
template <typename tTYPE>
struct is_SZug<tTYPE, typename std::enable_if<
std::is_same<tTYPE, typename SFoo<typename tTYPE::type>::SZug>{}
>::type>: public std::true_type { };
如果類型是SZug
,則對SBar
模板進行略微修改以啟用“專業化”:
template <typename tTYPE, typename Enabler = void>
struct SBar
{ static void g(); };
template <typename tTYPE>
struct SBar<tTYPE, typename std::enable_if<is_SZug<tTYPE>{}>::type>
{ static void f(); };
一點檢查:
void f () {
SBar<int>::g();
SBar<SFoo<int>::SZug>::f();
}
注意:您也可以直接將SFoo<T>
設置為SFoo<T>::SZug
的type
屬性,您只需要稍微更改std::is_same
的第二個參數std::is_same
。
您可以通過以下方式獲得想要的效果 (打印出0 1,BTW):
#include <type_traits>
#include <iostream>
namespace detail
{
struct SZugBase{};
}
template <typename tTYPE>
struct SFoo
{
struct SZug : public detail::SZugBase {};
};
template<typename tType, bool IsFoo>
struct SBarBase
{
int value = 0;
};
template<typename tType>
struct SBarBase<tType, true>
{
int value = 1;
};
template <typename tTYPE>
struct SBar : public SBarBase<tTYPE, std::is_convertible<tTYPE, detail::SZugBase>::value>
{ /* stuff */ };
int main()
{
SBar<int> b0;
SBar<SFoo<int>::SZug> b1;
std::cout << b0.value << " " << b1.value << std::endl;
}
說明
首先,我們為SZug
提供常規課程:
namespace detail
{
struct SZugBase{};
}
template <typename tTYPE>
struct SFoo
{
struct SZug : public detail::SZugBase {};
};
請注意以下幾點:
SZugBase
沒有任何參數,因此很容易獨立於SFoo
的參數進行SFoo
SZugBase
位於detail
名稱空間中,因此,按照通用的C ++約定,您要告訴客戶端代碼將其忽略。
現在,我們為SBar
兩個基類,專門針對某些東西是否可轉換為SZug
的非模板基:
template<typename tType, bool IsFoo>
struct SBarBase
{
int value = 0;
};
template<typename tType>
struct SBarBase<tType, true>
{
int value = 1;
};
最后,我們只需要使SBar
成為這些基礎的子類(取決於專業化):
template <typename tTYPE>
struct SBar : public SBarBase<tTYPE, std::is_convertible<tTYPE, detail::SZugBase>::value>
{ /* stuff */ };
請注意,您在這里不專門研究SBar
,而是專門研究基類。 但是,這有效地產生了相同的效果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.