从 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_();
    }
};

Demo