studying variadic fails

amid studying variadic, I fail to understand why this can't work

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <class T>
struct Accumulate {
	T s=0;
	
	Accumulate(){return;}
	template <class H, class...TL>
	Accumulate(H head, TL...tail) {
		s += head;
		Accumulate(tail...);
}
};


int main() {
	
  Accumulate<int> a(1, 2, 3, 4, 5);
  cout<<"total = " a.s <<"\n";
  
}

total = 1
Last edited on
If Accumulate is the name of the struct (and hence its constructor) then I think you will end up just creating a lot of temporary and unwanted Accumulate objects. std::cout << s; between lines 8 and 9 would show that.

This might be better just with an initialiser list input rather than variadic templates.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <initializer_list>

template <class T>
struct Accumulate
{
   T s = 0;
      
   Accumulate( const std::initializer_list<T> &L )
   {
      for ( T e : L ) s += e;
   }
};


int main()
{
   Accumulate<int> a{ 1, 2, 3, 4, 5 };
   std::cout << "total = " << a.s <<"\n";
}




If you have to use variadic templates then you could pass the arguments through to a separate function. There's a huge risk to me of this being called "fatuous", but hey-ho, there are worse problems in the world.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

template <class T>
struct Accumulate
{
   T s = 0;
      
   template <class... TL> Accumulate( TL... tail ){ add( tail... ); }

private:        
   void add() { return; }
   template <class... TL> void add( T head, TL...tail )
   {
      s += head;
      add( tail... );
   }
};


int main()
{
   Accumulate<int> a( 1, 2, 3, 4, 5 );
   std::cout << "total = " << a.s <<"\n";
}




I believe that in C++17 you can circumvent the base case and do something like the following. (It isn't available in cpp.sh at the moment, so I haven't put it in code tags.)

#include <iostream>

template <class T>
struct Accumulate
{
   T s = 0;
      
   template <class... TL> Accumulate( TL... tail ){ add( tail... ); }
        
private:
   template <class... TL> void add( TL... tail )
   {
      s = ( 0.0 + ... + tail );      // c++17 feature
   }
};


int main()
{
   Accumulate<int> a( 1, 2, 3, 4, 5 );
   std::cout << "total = " << a.s <<"\n";
}


Last edited on
Thanks... God bless you !
There's a huge risk to me of this being called "fatuous", but hey-ho, there's worse problems in the world.
When the Flying Nun stamps her foot and decides not to mollycoddle one the DuckDuckGo 'fatuous' label is permanently invoked. There is no escape. There is nothing worse.
Topic archived. No new replies allowed.