C++ 根据派生类字段指定基类模板参数

C++ 根据派生类字段指定基类模板参数,c++,templates,c++17,crtp,C++,Templates,C++17,Crtp,我希望能够根据派生类中数据成员的数量,将基类中数据成员的类型设置为尽可能小的类型。因此,如果派生类中的数据成员数为5,则基类中的数据成员类型应为std::uint8\t 以下是我已经尝试过的: 包括 样板 结构最小值{ 使用type=typename std::conditional\u t< N }; 样板 使用min\u t=typename min::type; 样板 结构包装器{ Tα; }; 结构Foo:包装器{ 静态constexpr int begin\uuuuuuu=\uuuuu

我希望能够根据派生类中数据成员的数量,将基类中数据成员的类型设置为尽可能小的类型。因此,如果派生类中的数据成员数为5,则基类中的数据成员类型应为std::uint8\t

以下是我已经尝试过的:

包括 样板 结构最小值{ 使用type=typename std::conditional\u t< N }; 样板 使用min\u t=typename min::type; 样板 结构包装器{ Tα; }; 结构Foo:包装器{ 静态constexpr int begin\uuuuuuu=\uuuuuuuu行\uuuuuuuu; 静态constexpr int F_A=0; 静态constexpr int F_B=0; 静态constexpr int F_C=0; 静态constexpr int end\uuuuuu=\uuuuuuuuu线; }; int main{ 富富,;
std::cout在CRTP中需要完整类型时的解决方法是不使用CRTP:,而是以另一种方式使用常规继承:

template <typename T, typename U = min_t<T::end__ - T::begin__ + 1>>
struct Wrapper : T {
    U a;
};

struct FooImpl {
    static constexpr int begin__ = __LINE__;
    static constexpr int F_A = 0;
    static constexpr int F_B = 0;
    static constexpr int F_C = 0;
    static constexpr int end__ = __LINE__;
};

using Foo = Wrapper<FooImpl>;

在CRTP中需要完整类型时,解决方法是不使用CRTP:,而是以另一种方式使用常规继承:

template <typename T, typename U = min_t<T::end__ - T::begin__ + 1>>
struct Wrapper : T {
    U a;
};

struct FooImpl {
    static constexpr int begin__ = __LINE__;
    static constexpr int F_A = 0;
    static constexpr int F_B = 0;
    static constexpr int F_C = 0;
    static constexpr int end__ = __LINE__;
};

using Foo = Wrapper<FooImpl>;

您可以将静态变量放在一个单独的栏中,让Foo从该栏和包装器继承


您可以将静态变量放在一个单独的栏中,让Foo从该栏和包装器继承



与此无关,像begin\uuuuu这样的名称是为实现保留的。看起来您需要反思。当前的解决方案,即使您让它工作起来,如果您甚至向Foo中添加空行,也会失败。无意冒犯,但在我看来,它似乎是XY问题。@cigien是的,我知道这一点没有改变it@StoryTeller-UnslanderMonica我认识一个人uld告诉我:…这是我目前正在处理的小型库:。我试图避免指定每个标记的数据类型。像begin_uuu这样的名称是为实现保留的。看起来您需要反思。当前的解决方案,即使您让它工作起来,如果您甚至向Foo添加空行,也会失败。No off是的,但在我看来这是个问题。@cigien是的,我意识到这一点并没有改变it@StoryTeller-UnslanderMonica我知道有人会告诉我:…这是我目前正在处理的小型库:。我试图避免指定每个标志的数据类型。只是一个次要问题:是否有可能将数据类型设置为如果每个f_A,f_B等都是用min_t计算的?我想你必须重新考虑你的依赖关系,也许是一个模板结构MyWrapper{/**/};会更合适。只是一个附带问题:是否有可能将每个F_A、F_B等的数据类型设置为使用最小值计算的数据类型?我认为您必须重新考虑依赖关系,可能是一个模板结构MyWrapper{/**/};会更合适。只有一个附带问题:是否有可能将每个F_A、F_B等的数据类型设置为使用最小值计算的数据类型?@Nutchracker为此添加了一个解决方案。也可以应用于Jarods的答案。谢谢。我从这两个答案中确实学到了很多。如果我只需要其中一个答案,我会再给你一个+1问:是否有可能将每个F_A、F_B等的数据类型设置为用min_t计算的数据类型?@NutCracker为此添加了一个解决方案。也可以应用于Jarods答案。谢谢。我从这两个答案中学到了很多。如果可以,我会再给你一个+1吗
template <typename T>
struct Bar {
    static constexpr int begin__ = __LINE__;
    static constexpr T F_A = 0;
    static constexpr T F_B = 0;
    static constexpr T F_C = 0;
    static constexpr int end__ = __LINE__;
};

struct Foo : Bar<Wrapper<Bar<int>>::type>, Wrapper<Bar<int>> {};