3

I implemented the template function below using variadic, but I am having difficulties in making it more generic. I am using MS VS C++ 2017.

This function essentially checks if an integer value is one of the values provided int templates argument. In theory should be equivalent to a list of logical OR.

template<int TFirst, int...TArgs>
constexpr bool foo(int&& a)
{
    if constexpr (sizeof...(TArgs) > 0)         
        return a == TFirst || foo<TArgs...>(std::forward<int>(a));    
    return a == TFirst;
}

int iii = 3;
assert(foo<1, 2, 3>(std::forward<int>(iii)); // ok!

I would like to make this function even more generic using other numeric types like double or class enums or even objects.

I tried the code below. It builds with integers, but NOT with doubles.

 template<typename T>
 struct check
 {
     template<T TFirst, T...TArgs>
     static constexpr bool foo(T&& a)
     {
         if constexpr (sizeof...(TArgs) > 0)
            return a == TFirst || foo<TArgs...>(std::forward<T>(a));
         return a == TFirst;
     }
 };

// test
int iii = 3;
double ddd = 4.0;

check<int>::foo<1, 2, 3>(std::forward<int>(iii));  // ok
check<double>::foo<1.0, 2.0, 3.0>(std::forward < double >(ddd )); // non ok

Error I have with double is

 error C2993: 'T': illegal type for non-type template parameter 'TFirst'
 error C2672: 'check<double>::foo': no matching overloaded function found

Is there any fix this or better way to make my function more generic?

Abruzzo Forte e Gentile
  • 14,423
  • 28
  • 99
  • 173
  • You can't use double values as template parameters, see the linked question for background information. There's no way around it, you will have to come up with some alternative approach that does not involve double template parameters. – Sam Varshavchik Mar 27 '19 at 12:31
  • @SamVarshavchik Can we not close this as a dupe but instead acknowledge they can't do what they have because of the dupe so how can they work around it. – NathanOliver Mar 27 '19 at 12:36
  • I see..so is like using literals string for template..interesting. I didn't think about it at all.Thanks for pointing me to the right response; I googled for similar questions but I was not able to find anything like that. – Abruzzo Forte e Gentile Mar 27 '19 at 12:57
  • @AbruzzoForteeGentile FWIW, you could write the code like [this](http://coliru.stacked-crooked.com/a/7de9a391d49ce51d) – NathanOliver Mar 27 '19 at 13:01
  • @Nathan. Wow! That's pretty hard-core! I never seen using the '...' like that? In fact I don't understand much how your function works (sorry). I am used to recursively call of a variadic template with less argument...I have no idea how your function is expanding. Can you point me to some useful tip for further reading or investigation? I found this usage truly amazing. – Abruzzo Forte e Gentile Mar 27 '19 at 13:44
  • @AbruzzoForteeGentile I used a [fold expression](https://en.cppreference.com/w/cpp/language/fold). It makes life soooooooo much easier. The gist of it is that `(find == in)` is the expression we want to do, and then we will or that with each additional `in`, so it expands out to `(find == in1) || (find == in2) || ... || (find == inN)` – NathanOliver Mar 27 '19 at 13:47
  • @NathanOliver Sir, I thank you very much for this input. It is a very interesting topic I was not aware and worth to explore. Have a great day! – Abruzzo Forte e Gentile Mar 27 '19 at 15:07

0 Answers0