c++templatestemplate-argument-deduction

How to make one function argument have priority when deducing template argument


I'm trying to write a set of util functions simplifying work with bit flags. One of them is

template< typename Flags >
void toggleFlag( Flags & targetFlags, Flags flagToSet, bool enabled )
{
    if (enabled)
        targetFlags |= flagToSet;
    else
        targetFlags &= ~flagToSet;
}

The problem is when i write something like

enum MyFlags : uint32_t
{
    Flag1 = (1 << 0),
    Flag2 = (1 << 1),
};
uint32_t myFlags;

toggleFlag( myFlags, MyFlags::Flag1, true );

i get an error: deduced conflicting types for parameter 'Flags' ('unsigned int' and 'MyFlags')

What i would like to do is to make the first function argument determine the template argument and then let the second function argument decay to that type. Is there any way i can do that?


Solution

  • You might use std::type_identity (C++20, but can be reimplemented for previous standard) to have a non-deduced context:

    template <typename Flags>
    void toggleFlag(Flags& targetFlags,
                    std::type_identity_t<Flags> flagToSet,
                    bool enabled)
    {
        if (enabled)
            targetFlags |= flagToSet;
        else
            targetFlags &= ~flagToSet;
    }