简体   繁体   English

从模板参数到构造函数参数

[英]From template parameter to constructor argument

Does C++17 (or earlier but not c++20) allow this? C++17(或更早但不是c ++ 20)是否允许这样做?

I need a type_traited conditional class, like a bitset with an internal 32 or 64 unsigned integer storage, depending if the template argument N is lesser then 32 or greater (please forget about more than 64 bits).我需要一个 type_traited 条件 class,就像一个内部 32 或 64 个无符号 integer 存储的位集,取决于模板参数 N 是否小于 32 或更大(请忘记超过 64 位)。

But the constraint is to finally implement two and only two classes for all possible cases.但约束是最终为所有可能的情况实现两个且仅两个类。 Next source code defines the problem using static and running time asserts:下一个源代码使用 static 和运行时间断言来定义问题:

Coliru link: http://coliru.stacked-crooked.com/a/d53a5b00bd828fb5 Coliru 链接: http://coliru.stacked-crooked.com/a/d53a5b00bd828fb5

#include <cassert>
#include <iostream>
#include <type_traits>

struct bitset32
{
    bitset32() : bits(0) { }
    bitset32(int _bits) : bits(_bits) { }

    const int bits;
    uint32_t value;
};

struct bitset64
{
    bitset64() : bits(0) { }
    bitset64(int _bits) : bits(_bits) { }
    
    const int bits;
    uint64_t value;
};

template <int N>
using bitset = std::conditional_t<(N<=32), bitset32, bitset64>;

int main ()
{
    static_assert(std::is_same<bitset<1>, bitset<2>>::value);
    static_assert(std::is_same<bitset<33>, bitset<34>>::value);
    static_assert(!std::is_same<bitset<1>, bitset<33>>::value);

    bitset<1> var1;
    bitset<15> var2;
    bitset<32> var3;
    bitset<64> var4;

    assert(var1.bits == 1);
    assert(var2.bits == 15);
    assert(var3.bits == 32);
    assert(var4.bits == 64);
}

Any solution is welcomend even if it changes the basic types and uses inheritance or whatever other mechanism necessary, but please, do not offer using a template function returning an object in the style of template<int N> make_bitset { return Bitset<N>(N); }欢迎任何解决方案,即使它更改了基本类型并使用 inheritance 或任何其他必要的机制,但请不要使用模板 function 返回 ZA8CFDE6331BD59EB2AC96F8911C4B6_66Z 以返回样式template<int N> make_bitset { return Bitset<N>(N); } template<int N> make_bitset { return Bitset<N>(N); } because it is needed to implement variables using this constructo Bitset<N> variable_name . template<int N> make_bitset { return Bitset<N>(N); }因为需要使用这个构造函数Bitset<N> variable_name来实现变量。

A new hypothesis, CTAD based基于CTAD的新假设

#include <cstdint>
#include <iostream>
#include <type_traits>

template <std::size_t>
struct BitSet;

template <>
struct BitSet<32u>
 {
   template <typename ... Ts>
   BitSet (Ts...) {}

   std::uint32_t value;
 };

template <>
struct BitSet<64u>
 {
   template <typename ... Ts>
   BitSet (Ts...) {}

   std::uint64_t value;
 };

template <typename ... Ts>
BitSet (Ts...) -> BitSet<(32 < sizeof...(Ts) ? 64u : 32u)>;


int main()
 {
   auto b1 = BitSet{1};
   auto b2 = BitSet{2};
   auto b3 = BitSet{0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
                    20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                    30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
   auto b4 = BitSet{0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
                    20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                    30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
                    40, 41, 42, 43, 44, 45, 46, 47, 48, 49};

   static_assert( std::is_same_v<decltype(b1), decltype(b2)> );
   static_assert( std::is_same_v<decltype(b1), BitSet<32u>> );
   static_assert( std::is_same_v<decltype(b3), decltype(b4)> );
   static_assert( std::is_same_v<decltype(b3), BitSet<64u>> );
 }

You can just make bitset32 and bitset64 templates like您可以制作bitset32bitset64模板,例如

template <std::size_t BitsUsed>
struct bitset32
{
    bitset32() : bits(BitsUsed) { }
    bitset32(int _bits) : bits(_bits) { }

    const int bits;
    uint32_t value;
};

template <std::size_t BitsUsed>
struct bitset64
{
    bitset64() : bits(BitsUsed) { }
    bitset64(int _bits) : bits(_bits) { }
    
    const int bits;
    uint64_t value;
};

and now the default constructor will pull in the correct number of bits.现在默认构造函数将引入正确的位数。 Then you just need to modify your alias like然后你只需要修改你的别名

template <int N>
using bitset = std::conditional_t<(N<=32), bitset32<N>, bitset64<N>>;

and you get the behavior you are asking for.你得到你要求的行为。

This will not work if you want to store a bitset<5> in the same container as a bitset<32> though since different template instantiations create distinct type.如果您想将bitset<5>存储在与bitset<32>相同的容器中,这将不起作用,因为不同的模板实例化创建不同的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM