首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法根据c++中的at模板参数来更改结构中使用的类型?

有没有办法根据c++中的at模板参数来更改结构中使用的类型?
EN

Stack Overflow用户
提问于 2020-06-06 09:54:59
回答 2查看 51关注 0票数 0

我想要的是一种根据模板参数使结构具有不同数据结构的方法

代码语言:javascript
复制
template<uint32_t width, uint32_t height>
struct S
{
    templateif (width * height) > 32:
        uint64_t val;
    templateelse:
        uint32_t val;
    templatend;
}

就像你上面看到的那样。有没有办法根据模板参数改变数据类型?

我想像这样的东西可能行得通:

代码语言:javascript
复制
struct S
{
    static const bool bit64 = (width * height) > 32;
    template <typename T>
    struct Arr
    {
        T val;
    }
    using DataType = Arr<bit64 ? uint64_t : uint32_t>;
    Arr data;
}

但事实并非如此。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-06 10:01:11

你可以试试std::conditional

代码语言:javascript
复制
template<std::uint32_t width, std::uint32_t height>
struct S
{
    using type = typename std::conditional<(width * height > 32), 
        std::uint64_t, std::uint32_t>::type;

    type val;
}
票数 3
EN

Stack Overflow用户

发布于 2020-06-06 16:25:47

代码语言:javascript
复制
#include <iostream>

// Define your conditions
template <int Fst, int Snd, typename = void>
struct is_bigger_than : std::false_type {};

template <int Fst, int Snd>
struct is_bigger_than <Fst, Snd, typename std::enable_if_t<(Fst > Snd), void>> : std::true_type {};

// Define short access ways to your conditions    
template <int Fst, int Snd>
constexpr bool is_bigger_than_v = is_bigger_than<Fst, Snd>::value;

// Define your base class
template <uint32_t width, uint32_t height, bool = is_bigger_than_v<width * height, 32>>
struct S {
    std::uint32_t val;

    S() {
        std::cout << "Smaller" << std::endl;
    }
};

// Partial specialized template class
template<uint32_t width, uint32_t height>
struct S<width, height, true> {
    uint64_t val;

    S() {
        std::cout << "Bigger" << std::endl;
    }
};

// Some tests
int main() {
    S<2,16> s1;
    S<2,17> s2;

    return EXIT_SUCCESS;
}

如果您有多个条件情况,则可以使用比true/false更多的变体。

编辑

我已经在我的新GitHub存储库中对条件is_bigger_than做了一些概括。现在,它将允许您以相同的方式执行更多的条件(包括使用general_compare_v的自定义条件):

代码语言:javascript
复制
template<int Fst, int Snd, typename Op, typename = void>
struct general_compare : std::false_type {};

template<int Fst, int Snd, typename Op>
struct general_compare<Fst, Snd, Op, typename std::enable_if_t<(Op()(Fst, Snd)), void>> : std::true_type {};

template<int Fst, int Snd, typename Op>
constexpr bool general_compare_v = general_compare<Fst, Snd, Op>::value;

// is_bigger_than

template<int Fst, int Snd>
constexpr bool is_bigger_than_v = general_compare_v<Fst, Snd, std::greater<>>;

template<int Fst, int Snd>
constexpr bool is_bigger_equal_v = general_compare_v<Fst, Snd, std::greater_equal<>>;

template<int Fst, int Snd>
constexpr bool is_lower_than_v = general_compare_v<Fst, Snd, std::less<>>;

// ... And some more ...

// Now you can define your classes in the same way I showed before:

// Define your base class
template <uint32_t width, uint32_t height, bool = is_bigger_than_v<width * height, 32>>
struct S {
    std::uint32_t val;
    // ...
};

// Partial specialized template class
template<uint32_t width, uint32_t height>
struct S<width, height, true> {
    uint64_t val;
    // ...
};

A link to the repository

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62226432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档