[英]Template argument calculation at compile time
我試圖在編譯時推斷出兩個模板參數中較大的一個。 兩個模板參數的類型都是size_t。
我有一個模板類型SomeType,它接受size_t作為模板參數。 然后我有一個函數,它接受兩個具有不同模板size_t的SomeType參數,並且我希望返回類型是SomeType,其模板化size_t是兩個輸入size_t大小中的較大者。
template <size_t d> struct SomeType {...}
template<size_t d1, size_t d2>
SomeType<the_larger_of_d1_and_d2> Func(SomeType<d1> A, SomeType<d2> B)
{
...
}
這可能嗎?
您可以直接計算類型,不需要SFINAE:
template<size_t d1, size_t d2>
SomeType<(d1 > d2 ? d1 : d2)> Func(SomeType<d1> A, SomeType<d2> B)
{
…
}
@KonradRudolph的解決方案當然是正確的。 但是如果你想深入研究模板元編程,那么學習Boost.MPL會很快得到回報。 它提供了一整套便利功能。 例如,您的問題可以解決
#include <iostream>
#include <boost/mpl/int.hpp>
#include <boost/mpl/max.hpp>
template<size_t d>
struct SomeType
:
boost::mpl::int_<d>
{};
template<size_t d1, size_t d2>
typename boost::mpl::max<SomeType<d1>, SomeType<d2> >::type
Func(SomeType<d1> A, SomeType<d2> B)
{
return typename boost::mpl::max<SomeType<d1>, SomeType<d2> >::type();
}
int main()
{
SomeType<2> st2;
SomeType<3> st3;
boost::mpl::max<SomeType<2>, SomeType<3> >::type res = Func(st2, st3);
std::cout << res.value;
}
實例 。
一些說明:
SomeType
繼承自boost::mpl::int_
賦予它一個type
和value
,以及一些方便的標簽。 這使得重用Boost.MPL中的其他元函數變得非常容易 boost::mpl::max
在幕后執行相同的三元技巧。 它更容易被IMO讀取,如果你想改變到另一個條件,那么這很容易。 如果您可以使用c ++ 11標准,則可以使用SFINAE標准支持:
template<size_t one, size_t two>
struct larger {
static constexpr typename std::enable_if<(one > two), size_t>::type value() {
return one;
}
static constexpr typename std::enable_if<(two >= one, size_t>::type value() {
return two;
}
};
然后
template<size_t d1, size_t d2>
SomeType<larger<d1, d2>::value()> Func(SomeType<d1> A, SomeType<d2> B)
{
...
}
由於我經常不得不一次又一次地查詢自己(我的舊代碼)關於這個問題,我決定制作一個GIT要點 ,以及允許(至少我)快速訪問某些“模板”代碼的編譯示例 (雙關語),使用元編程的條件類型選擇內容(也適用於'舊' c ++ 03標准):
選擇器聲明:
template<typename FalseType, typename TrueType, bool condition>
struct ConditionalTypeSelector {
typedef void ResultType;
};
選擇器專業化:
template<typename FalseType, typename TrueType>
struct ConditionalTypeSelector<FalseType,TrueType,false> {
typedef FalseType ResultType;
};
template<typename FalseType, typename TrueType>
struct ConditionalTypeSelector<FalseType,TrueType,true> {
typedef TrueType ResultType;
};
選定類型:
struct A {
unsigned char member;
};
struct B {
int member;
};
struct C {
long long member;
};
測試:
#include <iostream>
#include <typeinfo>
using namespace std;
int main() {
cout << typeid
( ConditionalTypeSelector
< A,B,(sizeof(A) > sizeof(B))>::ResultType
).name() << endl;
cout << typeid
( ConditionalTypeSelector
<A,B,(sizeof(B) > sizeof(A)) >::ResultType
).name() << endl;
cout << typeid
( ConditionalTypeSelector
< A,C,(sizeof(A) > sizeof(C))>::ResultType
).name() << endl;
cout << typeid
( ConditionalTypeSelector
< C,B,true>::ResultType
).name() << endl;
cout << typeid
( ConditionalTypeSelector
< C,A,false>::ResultType
).name() << endl;
return 0;
}
可以很容易地將此template
更改為使用例如用於專門選擇的enum
類型,或者應該檢查編譯時已知的任何其他常量條件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.