0

I wish to use a integer_sequence to judge if a range of numbers are all under a certain value: is_range() will return true, else return false, like below:

#include<utility> 
#include<iostream> 
using namespace std; 
template <std::size_t N, std::size_t... Ix> 
bool in_range(std::index_sequence<Ix...>) { 
   return ((Ix < N) && ...); 
} 
int main() 
{ 
     cout<<in_range<10>({1,2,30})<<endl; 
     cout<<in_range<10>(1,2,3)<<endl; 
     return 0; 
} 

I used clang3.8 to compile it, but failed.

$ clang++ m.cpp -std=c++1z 
m.cpp:5:37: error: template argument for template type parameter must be a type 
bool in_range(std::integer_sequence<Ix...>) { 
                                     ^~~~~ 
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/utility:229:21: note: 
       template parameter is declared here 
   template<typename _Tp, _Tp... _Idx> 
                     ^ 
m.cpp:10:11: error: no matching function for call to 'in_range' 
     cout<<in_range<10>({1,2,30})<<endl; 
           ^~~~~~~~~~~~ 
m.cpp:11:11: error: no matching function for call to 'in_range' 
     cout<<in_range<10>(1,2,3)<<endl; 
           ^~~~~~~~~~~~ 
3 errors generated.

How should I correct my code? I suppose my understanding of fold expression is incorrect

How to correct it?

2
  • The std::index_sequence expects a type as its first template argument. You are passing the size_t value Ix, which is an integer. Commented Jul 13, 2016 at 4:05
  • @MarvinSielenkemper : std::integer_sequence expects a type as its first template argument – std::index_sequence is the former for std::size_t. Commented Jul 13, 2016 at 21:05

1 Answer 1

3

There's no need for index_sequence here, you can just pass the list of numbers to be compared as template arguments.

template <std::size_t N, std::size_t... Ix> 
bool in_range() { 
   return ((Ix < N) && ...); 
}
cout<<in_range<10,1,2,30>()<<endl;

Or if you want to pass them as arguments to the function template

template <std::size_t N, typename... Ix> 
bool in_range(Ix... ix) { 
   return ((ix < N) && ...); 
}
cout<<in_range<10>(1U,2U,30U)<<endl; 

Finally, if you want to be able to pass a braced-init-list to in_range you should accept an initializer_list<size_t>. Otherwise, template argument deduction will fail because a braced-init-list is not an expression, and so it has no type.

template <std::size_t N> 
constexpr bool in_range(std::initializer_list<std::size_t> ix) { 
    for(auto i : ix) {
        if(i >= N) return false;
    }
    return true;
}
cout<<in_range<10>({1,2,30})<<endl; 

Live demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.