我试图在编译时推断出两个模板参数中较大的一个。两个模板参数的类型都是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)
{
...
}
这可能吗?
答案 0 :(得分:3)
您可以直接计算类型,不需要SFINAE:
template<size_t d1, size_t d2>
SomeType<(d1 > d2 ? d1 : d2)> Func(SomeType<d1> A, SomeType<d2> B)
{
…
}
答案 1 :(得分:1)
@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,如果你想改变到另一个条件,那么很容易做到。答案 2 :(得分:0)
如果您可以使用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)
{
...
}
答案 3 :(得分:0)
由于我经常不得不一次又一次地查询自己(我的旧代码)关于这个问题,我决定制作一个允许的GIT gist和compilation sample(至少我)快速访问一些“模板”代码(双关语),使用元编程的条件类型选择内容(也适用于'旧'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
类型,或者应该检查在编译时已知的任何其他常量条件。