Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ function with a viariable number of arguments of a certain type

I just learned about variadic templates in C++. I implemented it, but I want to know, can it do the following?

If I want a function with a variable number of arguments, I could do that:

template <typename... Ts>
f(Ts... args);

But I lose type safety (I don't know the type of the arguments).

What if I know my function needs only float as arguments? I want to make sure at compile-time that every argument is the type I want.

So these are my questions:

  • Is there a way to force a certain type with variadic templates (something like this)?

    template <float... Fs>
    f(Fs... args); // unlimited number of arguments but only float
    
  • If not, is there a way to check it at compile-time? static_assert(std::is_same<A,B>) is fine in most cases, but it doesn't work for templated classes (like for my use case):

    template <typename T, uint16_t dimension>
    class Vector
    {
        template <typename... Ts>
        Vector(Ts... args)
        {
            static_assert(sizeof...(args) == dimension);
            static_assert(std::is_same_v<Ts..., T>()); //doesn't work because Ts will
                                                       //develop into a lot of template 
                                                       //arguments. Just putting Ts doesn't
                                                       //work either.
        }
    }
    

Ps: Yes I could use std::vector or std::array as arguments, but that's not really the point. Plus, I want to keep the beautiful Vector(2.0, 1.0, 0.0) syntax, not using curly braces.

like image 290
EloiGG Avatar asked Oct 29 '25 18:10

EloiGG


1 Answers

template <typename T, uint16_t dimension>
class MyVector
{
  public:
    template <typename... Ts>
    MyVector(Ts... args)
    {
        static_assert(sizeof...(args) == dimension);
        static_assert((std::is_same<T,Ts>::value && ...) );
    }
};

Can also use the unary right fold expression as provided in C++17 https://en.cppreference.com/w/cpp/language/fold

This essentially does

std::is_same<T,Ts_1>::value && ( std::is_same<T,Ts_2>::value && ... std::is_same<T,Ts_n>::value ) ...)

And works also when the parameter pack Ts is empty. Quote from the reference link:

" Logical AND (&&). The value for the empty pack is true"
like image 156
Let's do it Avatar answered Nov 01 '25 09:11

Let's do it



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!