从 class 构造函数中推导出 class 模板参数
Deduce class template arguments from class constuctor
我想让编译器从构造函数中部分推导出 class 模板参数。
动机是编写一个协议库,其中某些数据的存在(此处为位长度)取决于最后一个变量的值,因此必须使用条件 class 对其进行建模。
我想要实现的 c++ 代码应该像这样工作,但我想以更具表现力和简化的方式实现它,而不必在模板中设置所有参数,而是让编译器推导它们:
科里鲁 link: https://coliru.stacked-crooked.com/a/bb15abb2a9c09bb1
#include <iostream>
template<typename T1, typename T2, typename F, int... Ints>
struct If : T1
{
const T2& condition;
constexpr If(const T2& cond) : condition(cond) {}
constexpr int bits() { return check() ? T1::bits : 0; }
constexpr bool check()
{
return (F{}(Ints, condition.value) || ...);
}
};
struct Variable1
{
int value{};
static constexpr int bits{ 5 };
};
struct Variable2
{
int value{};
static constexpr int bits{ 8 };
};
struct Datagram
{
Variable1 var1;
If<Variable2, Variable1, std::equal_to<int>, 1, 2> var2{ var1 };//It compiles and works OK under c++17. What I have...
//If<Variable2> var2{ var1, std::equal_to<int>{}, 1, 2 };// ...what I wish
};
int main()
{
Datagram data;
data.var1.value = 0;
std::cout << data.var2.bits() << "\n";//must be 0
data.var1.value = 1;
std::cout << data.var2.bits() << "\n";//must be 8
data.var1.value = 2;
std::cout << data.var2.bits() << "\n";//must be 8
}
这可能吗?
您可能正在寻找的概念是“类型擦除”,例如通过 std::function
。沿着这些线的东西:
template<typename T1>
struct If : T1
{
std::function<bool()> checker_;
template <typename T2, typename F, typename... Args>
constexpr If(const T2& cond, F&& f, Args&&... args)
: checker_([=, &cond]() { return (f(args, cond.value) || ...); })
{}
constexpr int bits() { return check() ? T1::bits : 0; }
constexpr bool check()
{
return checker_();
}
};
我想让编译器从构造函数中部分推导出 class 模板参数。
动机是编写一个协议库,其中某些数据的存在(此处为位长度)取决于最后一个变量的值,因此必须使用条件 class 对其进行建模。
我想要实现的 c++ 代码应该像这样工作,但我想以更具表现力和简化的方式实现它,而不必在模板中设置所有参数,而是让编译器推导它们:
科里鲁 link: https://coliru.stacked-crooked.com/a/bb15abb2a9c09bb1
#include <iostream>
template<typename T1, typename T2, typename F, int... Ints>
struct If : T1
{
const T2& condition;
constexpr If(const T2& cond) : condition(cond) {}
constexpr int bits() { return check() ? T1::bits : 0; }
constexpr bool check()
{
return (F{}(Ints, condition.value) || ...);
}
};
struct Variable1
{
int value{};
static constexpr int bits{ 5 };
};
struct Variable2
{
int value{};
static constexpr int bits{ 8 };
};
struct Datagram
{
Variable1 var1;
If<Variable2, Variable1, std::equal_to<int>, 1, 2> var2{ var1 };//It compiles and works OK under c++17. What I have...
//If<Variable2> var2{ var1, std::equal_to<int>{}, 1, 2 };// ...what I wish
};
int main()
{
Datagram data;
data.var1.value = 0;
std::cout << data.var2.bits() << "\n";//must be 0
data.var1.value = 1;
std::cout << data.var2.bits() << "\n";//must be 8
data.var1.value = 2;
std::cout << data.var2.bits() << "\n";//must be 8
}
这可能吗?
您可能正在寻找的概念是“类型擦除”,例如通过 std::function
。沿着这些线的东西:
template<typename T1>
struct If : T1
{
std::function<bool()> checker_;
template <typename T2, typename F, typename... Args>
constexpr If(const T2& cond, F&& f, Args&&... args)
: checker_([=, &cond]() { return (f(args, cond.value) || ...); })
{}
constexpr int bits() { return check() ? T1::bits : 0; }
constexpr bool check()
{
return checker_();
}
};