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>