Template operator in template class

Hi all, I've looked around to try and understand this problem, but I can't figure it out; a little help would be greatly appreciated!

I'm trying to define a template method inside a template class:

Header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#ifndef __TEST_TEMPLATE_OPERATOR__
#define __TEST_TEMPLATE_OPERATOR__

#include <array>
using namespace std;



/* Class definition */
template <class T, size_t n>
class A : public array<T,n>
{
	template <class OutType, class InType>
	A<OutType,n>&& operator+ ( const A<InType,n> &other ) const;
};



/* Define operator */
template <class T, size_t n> 
	template <class OutType, class InType>
A<OutType,n>&& 
A<T,n>::operator+ ( const A<InType,n> &other ) const
{
	// Initialize output
	A<OutType,n> output; 

	// Prepare iterators
	auto a = this->cbegin(); 
	auto c = output.begin();

	// Compute sum
	for ( auto b = other.cbegin(); b != other.cend(); ) 
		*c++ = static_cast<OutType>( *a++ + *b++ );

	// Return result
	return output;
}

#endif 


Implementation
1
2
3
4
5
6
7
8
#include "test_template_operator.h"


int main(int argc, char const *argv[])
{
	A<float,42> a; A<double,42> b;
	A<short,42> c = a + b;
}


And here is the error:
1
2
test_template_operator.cpp: In function ‘int main(int, const char**)’:
test_template_operator.cpp:7: error: no match foroperator+’ in ‘a + b’
OutType cannot be deduced.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <array>
#include <type_traits>
#include <algorithm>

template < typename T, typename U, std::size_t N >
std::array< typename std::common_type<T,U>::type, N >
operator+ ( const std::array<T,N>& a, const std::array<U,N>& b )
{
    std::array< typename std::common_type<T,U>::type, N > result ;
    std::transform( a.begin(), a.end(), b.begin(), result.begin(),
                    []( const T& aa, const U& bb ) { return aa + bb ; } ) ;
    return result ;
}

int main()
{
	std::array<int,42> a ;
	std::array<double,42> b ;
	auto c = a + b;
}
Arr that's what I thought at some point, but the error blamed the operator, not the output type...
Thanks a lot JLBorges, you're always helpful! I have two other questions about your solution;
1/ I there no way (other than writing a function with three inputs) to perform both addition and cast within the operator? Using common_type is a little annoying here, because then I have to cast the values when I use them / iterate again and cast them in another container..
2/ Is there any overhead calling transform instead of actually writing the for loop? I was wondering about that lately..
> I there no way (other than writing a function with three inputs)
> to perform both addition and cast within the operator?

No. The the operator being overloaded is a binary operator.

We can do it in two steps, though; first the operator+() and then a copy initialization or assignment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <array>
#include <type_traits>
#include <algorithm>

template < typename T, std::size_t N > struct my_array : public std::array<T,N>
{

    template < typename U >
    my_array< typename std::common_type<T,U>::type, N >
    operator+ ( const std::array<U,N>& that ) const
    {
        my_array< typename std::common_type<T,U>::type, N > result ;
        std::transform( this->begin(), this->end(), that.begin(), result.begin(),
                        []( const T& aa, const U& bb ) { return aa + bb ; } ) ;
        return result ;
    }

    my_array() = default ;

    template < typename U >
    my_array<T,N>( const std::array<U,N>& that )
    {  std::copy( that.begin(), that.end(), this->begin() ) ; }

    template < typename U >
    my_array<T,N>&  operator= ( const std::array<U,N>& that )
    {
        std::copy( that.begin(), that.end(), this->begin() ) ;
        return *this ;
    }

};

int main()
{
	my_array<int,42> a ;
	my_array<double,42> b ;
	my_array<short,42> c = a + b;
}



> Is there any overhead calling transform instead of actually writing the for loop?

No. One would expect the call to transform() to be inlined.
Thank you so much again for taking the time to give me these explanations :)
Question solved!
Topic archived. No new replies allowed.