2

I have this code:

template<char... Ts>
class  myIDClass 
{
protected:
       std::vector<uint8_t> m_ID = { Ts... };

public:
       std::vector<uint8_t> getID()
        {
             return m_ID;
        }
}

and I can use it in this way:

class   MyClass: myIDClass<'1','2','3','4','5','6','7','8'>
{
  // some code here
}

MyClass mc;

But I want to make sure that the person that uses myIDClass enter exactly 8 character to enter as template parameter to the class. How can I do during compilation?

Is there anyway that I can do this using of static_asset?

mans
  • 17,104
  • 45
  • 172
  • 321
  • 4
    why do you use `std::vector` and not `std::array` if the size should be a compile time constant? – 463035818_is_not_an_ai Dec 11 '17 at 12:46
  • 2
    What's wrong with the old-fashioned way: create a constructor taking 8 arguments? – Bathsheba Dec 11 '17 at 12:52
  • 1
    ...and why do you use a variadic parameter list when you dont want it to be variadic ? ;) – 463035818_is_not_an_ai Dec 11 '17 at 12:57
  • @tobi303 How to use an array instead of a vector? – mans Dec 11 '17 at 12:58
  • @Bathsheba old fashioned is slow as the initialization of vector (or array) is done during run time and not compile time. – mans Dec 11 '17 at 12:59
  • simply replace your `std::vector` with an `std::array` of a fixed size of 8. I am not familiar with brace initalization, but perhaps `std::array` accepts only initializers of the right size, if not then I would still use `array` instead of `vector` even if the only consequence would be to give it the right name – 463035818_is_not_an_ai Dec 11 '17 at 13:01
  • @tobi303 How to use a fixed size parameter? The idea is to send a buffer that has 8 byte of data? the 8 byte is fixed at compile time and should be changed at anytime later when somebody uses the class. – mans Dec 11 '17 at 13:01
  • sry, not sure if I understand you correctly.... `array`s second template parameter is its size, that needs to be fixed at compile time. If you know it is 8 then just use an array of size 8 – 463035818_is_not_an_ai Dec 11 '17 at 13:03
  • @tobi303 I tried to use an array (old fashioned uint8_t m_ID[]={ Ts... };) but it don;t compiled. – mans Dec 11 '17 at 13:03
  • I am talking about `std::array` not c-style arrays – 463035818_is_not_an_ai Dec 11 '17 at 13:08
  • I updated my answer to show how to use `std::array`. – Nikos C. Dec 11 '17 at 13:12

1 Answers1

2

Sure:

template<char... Ts>
class myIDClass
{
    static_assert(sizeof...(Ts) == 8, "myIDClass needs 8 template arguments");

    // ...

However, since you know at compile time that you want exactly 8 values, you can use std::array instead:

#include <array>
// ...

template<char... Ts>
class  myIDClass 
{
    // The assertion is not actually needed, but you might still want to keep
    // it so that the user of the template gets a better error message.
    static_assert(sizeof...(Ts) == 8, "myIDClass needs 8 template arguments");

protected:
    std::array<uint8_t, 8> m_ID = { Ts... };

public:
    std::array<uint8_t, 8> getID()
    {
        return m_ID;
    }
};

In this case, you don't need the static_assert anymore. However, the error message the user of the template gets when not using exactly 8 arguments can be confusing. The assertion in this case helps with giving out a better error message.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96