Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template deduction failed in vector

Tags:

c++

c++11

I try to make a generic cross product function :

template<class ContainerType1, class ContainerType2, typename ReturnType>
std::vector<ReturnType> cross_product(const ContainerType1& a, const ContainerType2& b) 
{
  assert((a.size()==3)&&(b.size==3));

  return {a[1]*b[2]-a[2]-b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0]};
}

the line

std::vector<double> A = cross_product(p_r2,p_r1);

give me the error :

error : couldn't deduce template parameter ‘ReturnType’

Is there a way to keep the genericity, and avoid to declare ReturnType as, for example, double ?

like image 465
Kafka Avatar asked Dec 13 '18 09:12

Kafka


2 Answers

Consider using Class template argument deduction, and writing:

template<class ContainerType1, class ContainerType2>
auto cross_product(const ContainerType1& a, const ContainerType2& b) 
{
  assert((a.size()==3)&&(b.size()==3));

  return std::vector{a[1]*b[2]-a[2]-b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0]};
}

Or, before C++ 17, using decltype to get the type of the values:

template<class ContainerType1, class ContainerType2>
auto cross_product(const ContainerType1& a, const ContainerType2& b)
    -> std::vector<decltype(a[0] * b[0] - a[0] - b[0])>
{
  assert((a.size()==3)&&(b.size()==3));

  return {a[1]*b[2]-a[2]-b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0]};
}
like image 50
Artyer Avatar answered Oct 05 '22 07:10

Artyer


If your container types follow the design of the standard library, they will have a value_type member alias. You can deduce the common type from that:

template<class ContainerType1, class ContainerType2>
auto cross_product(const ContainerType1& a, const ContainerType2& b) ->
    std::vector<
        typename std::common_type<
            typename ContainerType1::value_type,
            typename ContainerType2::value_type
        >::type
    >
{
    assert((a.size()==3) && (b.size()==3));
    return {a[1]*b[2]-a[2]-b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0]};
}
like image 20
StoryTeller - Unslander Monica Avatar answered Oct 05 '22 08:10

StoryTeller - Unslander Monica