Home > other >  Compilation error passing class template as template parameter
Compilation error passing class template as template parameter

Time:01-20

I wrote code like below:

#include <type_traits>

template <typename T>
class myTemplateClass
{
public:
    myTemplateClass(T t)
        : val{t}
    {}
    T val;
};

template <template<typename> class TT, typename T>
auto create(T val)
requires std::is_same_v<TT<T>, myTemplateClass<T>>
{
    return TT<T>(val);
};


int main()
{
    auto result =  create<myTemplateClass<int>>(10);
    // or
    auto result = create(static_cast<int>(10));
}

But both of the create function calls has failed to build.

Error for the 1st call (on MSVC):

error C2672: 'create': no matching overloaded function found
error C3207: 'create': invalid template argument for 'TT', class > template expected

Error for the 2nd call (on MSVC):

error C2672: 'create': no matching overloaded function found
error C2783: 'auto create(T)': could not deduce template argument for 'TT'

I expected the following to compile:

    auto result = create(static_cast<int>(10));

CodePudding user response:

create is dependant on 2 template parameters: TT and T.
Therefore one way to do what you want is to mention them explicitly:

//-------------------vvvvvvvvvvvvvvv--vvv-----
auto result = create<myTemplateClass, int>(10);

An altenative way (in which the int is deduced) is mentioned in the comment above (by @songyuanyao):

auto result = create<myTemplateClass>(10);

CodePudding user response:

With

template <template<typename> class TT, typename T>
auto create(T val)
requires std::is_same_v<TT<T>, myTemplateClass<T>>;

Way to call it would be

create<myTemplateClass>(42);
create<myTemplateClass, int>(42);

To allow

auto result =  create<myTemplateClass<int>>(10);

You would need:

template <typename TT, typename T>
auto create(T val)
requires std::is_same_v<TT, myTemplateClass<T>>
{
    return {val};
}

To allow

auto result =  create(10); // myTemplateClass<int>

You would need:

template <typename T>
auto create(T val) -> myTemplateClass<T>
{
    return {val};
}

Note

Notice that create (std uses make_xx as std::make_optional/std::make_pair/...) is not really needed with CTAD (C 17), you might write:

auto result =  myTemplateClass(10); // myTemplateClass<int>
  • Related