Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we use parameter packs as std::vector initializers?

I'm experimenting with C++11 (I've used old C++ so far) and I wrote the following code:

#include <iostream>
#include <vector>
#include <type_traits>

using namespace std;

constexpr bool all_true(){
    return true;
}

template <typename Head, typename... Tail>
constexpr bool all_true(Head head, Tail... tail){
    static_assert( is_convertible<bool, Head>::value, "all_true arguments must be convertible to bool!");
    return static_cast<bool>(head) && all_true(tail...);
}

template<typename T, typename... Args>
void print_as(Args... args){
    static_assert( all_true(is_convertible<T,Args>::value...), "all arguments must be convertible to the specified type!");
    vector<T> v {static_cast<T>(args)...};
    for(T i : v) cout << i << endl;
}

int main(){
    print_as<bool>(1, 2, 0, 4.1);
}

The code compiles and runs as expected (I used gcc 4.6). I would like to aks the following questions:

  1. I initialized a std::vector with an expanded parameter pack ( vector v {static_cast(args)...}; ). Is this correct C++11? I haven't found this feature explained anywhere.
  2. I don't like too much the declaration of all_true because I know the type but I use templates. Is it possible to use something similar to the following?

    constexpr bool all_true(bool head, bool... tail){...} // This code doesn't compile
    

Thanks!

like image 504
carlo Avatar asked Oct 20 '22 19:10

carlo


1 Answers

  1. Yes, it is possible to use pack expansions inside initialiser lists. C++11 [temp.variadic]§4 allows this:

    ... Pack expansions can occur in the following contexts: ...

    • In an initializer-list (8.5); the pattern is an initializer-clause.
  2. No, there's no way to make a non-template typesafe variadic function. What you have is OK. There was a question about this recently.

like image 102
Angew is no longer proud of SO Avatar answered Oct 23 '22 23:10

Angew is no longer proud of SO