这是一个模板lessThan
,它作为一个功能。
template<int n>
struct Box
{
};
template<typename T>
struct Unbox_;
template<int n>
struct Unbox_<Box<n>>
{
static constexpr int value = n;
};
template<typename T>
constexpr int unbox = Unbox_<T>::value;
template<typename T, typename U>
struct LessThan_
{
static constexpr bool value = unbox<T> < unbox<U>;
};
template<typename T, typename U>
constexpr bool lessThan = LessThan_<T, U>::value;
#include <iostream>
int main()
{
std::cout << lessThan<Box<1>, Box<2>> << '\n';
std::cout << lessThan<Box<3>, Box<2>> << '\n';
}
我现在想做这样的事情
lessThan<Box<1>><Box<2>> == true
当然不是有效的C ++。我为什么需要这个?请考虑以下内容。
template<typename T>
struct LessThanOne_
{
static constexpr bool value = unbox<T> < 1;
};
template<typename T>
constexpr bool lessThanOne = LessThanOne_<T>::value;
在某些需要传递带有一个参数的模板的地方,我希望传递lessThanOne
这样的内容,而不是传递lessThan<Box<1>>
,这样我就不需要对所有内容进行硬编码案例。有没有解决方法?
答案 0 :(得分:2)
您正在寻找calked currying的概念。仔细看看。这是一个快速抛出的示例实现:
template<template<class,class> class fn>
struct curry
{
template <class A>
struct apply1
{
template <class B>
using apply = fn<A,B>;
};
template<class A>
using apply = apply1<A>;
};
// That's it. Below is a test rig.
template <class>
struct test1 {};
template <template<class>class>
struct test2{};
// a meta function to test
template <class, class>
struct myfn {};
// same function, curried
using myfngood = curry<myfn>;
// fully applied myfngood is a type
test1 <myfngood::apply<int>::apply<char*>> t1;
// partially applied myfngood is a template
test2 <myfngood::apply<int>::apply> t2;
答案 1 :(得分:0)
作为RedX的评论:
template<typename RHS>
struct LessThanN {
template <typename LHS>
struct inner {
static constexpr bool value = unbox<LHS> < unbox<RHS>;
};
};
并使用它:
template <typename LHS>
using LessThanOne = LessThanN<Box<1>>::inner<LHS>;
int main() {
auto x = LessThanN<Box<2>>::inner<Box<1>> {};
cout << "1<2 " << boolalpha << x.value << '\n';
cout << "3<2 " << boolalpha << LessThanN<Box<2>>::inner<Box<3>>::value << '\n';
cout << "0<1 " << boolalpha << LessThanOne<Box<0>>::value << '\n';
}
话虽如此,如果你纠正语法错误,你原来的动机例子似乎是完全可行的,尽管它没有处理部分应用:
template<typename T, typename U>
struct LessThan_ {
static constexpr bool value = unbox<T> < unbox<U>;
};
template<typename T, typename U>
constexpr bool lessThan = LessThan_<T, U>::value;
static_assert(lessThan<Box<1>, Box<2>> == true, "check");
// NOT lessThan<Box<1>><Box<2>> == true