Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constexpr if testing one template parameter

If I have a class that has two template parameters, is there any way to branch an if constexpr on just one of those parameters? In the following example I can test if both parameters match, but I would like a single way of matching any version of MyTemplateClass that has char as its first parameter.

#include <iostream>
#include <type_traits>

template<typename T,int32_t N>
class MyTemplateClass
{

};

template<typename C>
void DoStuff(const C& myObj)
{
    if constexpr(std::is_base_of_v<MyTemplateClass<char,64>, C>) // how do I remove the hardcoded 64?
    {
        // test passed!
    }
    else
    {
        static_assert(false);
    }
}


int main()
{
    MyTemplateClass<char, 64> passesObj;
    MyTemplateClass<char, 128> shouldPassObj;
    MyTemplateClass<wchar_t, 64> failsObj;

    DoStuff(passesObj);  // passes correctly
    DoStuff(shouldPassObj); // currently fails, want to make pass
    DoStuff(failsObj); // correctly fails
}
like image 447
Iain Brown Avatar asked Dec 28 '25 22:12

Iain Brown


1 Answers

You're too focused on new language features instead of old techniques. If you want a template function that only works if the type given is any instance of MyTemplateClass which takes as its first parameter char, then write that:

template<int32_t N>
void DoStuff(const MyTemplateClass<char, N> &myObj)
{
  // test passed!
}

This is standard template argument deduction, not C++17 if constexpr gymnastics. This will fail to be called for any type other than one generated from the MyTemplateClass template instantiated with char.

It's possible to have a more generalized solution using template parameter packs, but since all parameters in a pack must be of one kind of template parameter (type, value, or template), you wouldn't be able to mix type and value template parameters in the same pack:

template<typename ...Args>
void DoStuff(const SomeClass<known, params, ...Args> &myObj);

That would only work if the extra arguments are type parameters, not value or template parameters. You could make Args a value parameter pack with auto, but then they couldn't be types. C++ has no mechanism to make a template parameter of known kind.

like image 174
Nicol Bolas Avatar answered Dec 31 '25 11:12

Nicol Bolas



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!