I have a problem compiling this code.
All I am trying to do is create a variadic class template that can give me the sum of all elements that are passed in (eg. 1,2,3,4,5,6 should give 21) whether it's int or float. I could basically do it with two function templates recursively for which I'm getting the answer correctly but when I'm implementing it in class it doesn't give me an answer.
template <typename T>
class Myclass
{
public:
T sum;
T func(T A,T... B)
{
sum+=A;
func(B...);
}
T func(T A)
{
sum+=A;
return sum;
}
};
int main()
{
Myclass<int> myclass;
cout<<myclass.func(12,11,11,23);
return 0;
}
Your code does not compile because T... is an invalid variadic expansion, as T is not a parameter pack.
You code has also several other issues. I will address them in the snippet below:
template <typename T>
class Myclass
{
public:
// `sum` needs to be initialized to a value, otherwise its value
// will be undefined.
T sum = 0;
// `TRest...` is a template variadic type pack.
template <typename... TRest>
T func(T A, TRest... B)
{
sum+=A;
// You need to return from the recursive case of `func`.
return func(B...);
}
T func(T A)
{
sum+=A;
return sum;
}
};
working wandbox example
Note that the values matched in TRest... can be of any type. If you want to force them to be T, you can use the following technique (or static_assert):
template <typename...>
using force_to_t = T;
// ...
T func(T A, force_to_t<TRest>... B)
{
sum+=A;
// You need to return from the recursive case of `func`.
return func(B...);
}
I learned this solution thanks to Piotr's answer on another question.
T func(T A,T... B)
{
sum+=A;
func(B...);
}
This is not valid C++ syntax when func is not a function template with T its template parameter pack. ... can only be used to expand packs; T is a non-pack template parameter of the class template.
There are two ways to do this, depending on what you want to achieve.
One: If you want func to accept a mix of arbitrary types, you can make it a (member) function template:
template <typename T>
class Myclass
{
public:
T sum;
template <class F1, class... F>
T func(F1 A, F... B)
{
sum+=A;
func(B...);
return sum;
}
template <class F>
T func(F A)
{
sum+=A;
return sum;
}
};
Two: If you want func to only accept Ts, you can change it to use an initializer list:
template <typename T>
class Myclass
{
public:
T sum;
T func(std::initializer_list<T> A)
{
for (const auto& a : A)
sum+=a;
return sum;
}
};
Note that this will require calling it with a list in braces (e.g. func({1, 2, 42}) instead of func(1, 2, 42), but it's the approach also taken by e.g. std::max.
Notice that there are a few issues in your code unrelated to the question at hand.
One, which I fixed in the example above, is that your first overload of func didn't return anything. Calling it would result in Undefined Behaviour.
Another one, pointed out by #Zereges in the comments, is that T sum is not initialised explicitly. If MyClass is instantiated with a POD type (such as int or double), it will be used uninitialised. You should add a constructor for Myclass:
Myclass() : sum{} {}
You can avoid the need for recursive calls by writing the sequential sum+=A as an initialiser for a std::initializer_list:
template <typename T>
class Myclass
{
template <class... F>
T func_impl(F... A)
{
std::initializer_list<int>{
((void)(sum+=A), 0)...};
return sum;
}
public:
Myclass() :sum(){}
T sum;
template <class F1, class... F>
T func(F1 A, F... B)
{
return func_impl(A, B...);
}
};
You can do that with another approach that avoid recursive call.
template <typename T>
class Myclass
{
public:
T sum;
Myclass() { sum = 0; }
template<typename ...T1>
T func(T1 ... args)
{
auto l_expansion_list =
{
(
[this, &args]()
{
this->sum += args;
return true;
}()
)...
};
return sum;
}
};
Related
How can I store the addresses of the arguments,
and make the function use them instead of the values it was initialized with?
This is not a running code, just the goal I would like to achieve.
class Class {
private:
Function function_; // e.g. : int Sum(int a, int b) { return a+b; } ;
std::tuple<Args...> args; // a,b provided are static consts.
public:
Class(Function _function, Args... _args) :
function_ { std::forward<Function>(_function) }
args{std::make_tuple( std::forward<Args>(_args)...) }
{}
void run_fucntion()
{
// use the addresses of a,b
function_( *p_a, *p_b ... ) // How do I do that?
}
You can use std::apply to apply the tuple of reference (not pointer but it do refer to the original object)
note: not sure what p_a and p_b supposed to be, but you can add then to the tuple with std::tuple_cat
#include <tuple>
template <typename F,typename ... Args>
class Class {
private:
F function;
std::tuple<Args...> args;
public:
Class(F&& function, Args&&... _args):
function(std::forward<F>(function)),
args{std::forward<Args>(_args)...}
{}
decltype(auto) run_fucntion()
{
return std::apply(function,args);
}
};
template <typename F,typename...Args>
Class(F&&,Args&&...) -> Class<F&&,Args&&...>;
auto f(int x){
return Class([](int a,int b){return a+b;},1,x).run_fucntion();
}
https://godbolt.org/z/jnY9sod94
if this is what you want, you can even pack them at first place
template <typename F,typename ... Args>
class Class {
private:
std::function<std::invoke_result_t<F,Args...>()> function;
public:
Class(F&& f, Args&&...args)
:function([&]{return std::forward<F>(f)(std::forward<Args>(args)...);}){}
decltype(auto) run_fucntion(){
return function();
}
};
template <typename F,typename...Args>
Class(F&&,Args&&...) -> Class<F&&,Args&&...>;
I am writing an identity function for some of my classes that keeps a count of its calls (long story -> short: metrics).
At the moment, I'm trying to figure the performance differences/benefits of using a template vs auto.
Here is a short example taken from my code of what I'm doing:
namespace Metrics {
unsigned long identifications = 0;
//auto version
auto identity(auto i) {
//... other stuffs
identifications++;
return i;
};
//template version
template<class I> I identity(I i) {
//... other stuffs
identifications++;
return i;
};
};
There's a bit more going on, but that is the basics. I know the compiler will just make a function for each, i.e.
identity(5);
identity("5");
//generates the functions
int identity(int i) { ... return i; };
const char* identity(const char* i) { ... return i; };
At run-time, which one is faster?
And do they have a compile time difference?
Since this function is meant to be called a lot, I'm more interested in run-time performance, but there also could be a large amount of types to generate the function for, so I'm also interested in which one would be faster at compile-time.
auto identity(auto i)
{
//...
return i;
}
is a shorthand for
template <class T>
auto identity(T i)
{
// ...
return i;
}
which in turn is a shorthand for
template <class T>
T identity(T i)
{
// ...
return i;
}
So no difference whatsoever.
Not applicable to your example, but if you are going to use auto parameters you need to be aware of some gotchas:
auto as return type
auto foo(auto a)
Does not mean
// not this
template <class T>
T foo(T a)
The return type will be deduced from the return expression(s) in foo definition, just like any auto return type. It just happens that in your function the return type is deduced to be the same as the parameter type.
Multiple auto parameters
void foo(auto a, auto b)
Is not equivalent to
// not this
template <class T>
void foo(T a, T b)
but with
template <class T, class U>
void foo(T a, U b)
I am writing an identity function for some of my classes that keeps a count of its calls (long story -> short: metrics).
At the moment, I'm trying to figure the performance differences/benefits of using a template vs auto.
Here is a short example taken from my code of what I'm doing:
namespace Metrics {
unsigned long identifications = 0;
//auto version
auto identity(auto i) {
//... other stuffs
identifications++;
return i;
};
//template version
template<class I> I identity(I i) {
//... other stuffs
identifications++;
return i;
};
};
There's a bit more going on, but that is the basics. I know the compiler will just make a function for each, i.e.
identity(5);
identity("5");
//generates the functions
int identity(int i) { ... return i; };
const char* identity(const char* i) { ... return i; };
At run-time, which one is faster?
And do they have a compile time difference?
Since this function is meant to be called a lot, I'm more interested in run-time performance, but there also could be a large amount of types to generate the function for, so I'm also interested in which one would be faster at compile-time.
auto identity(auto i)
{
//...
return i;
}
is a shorthand for
template <class T>
auto identity(T i)
{
// ...
return i;
}
which in turn is a shorthand for
template <class T>
T identity(T i)
{
// ...
return i;
}
So no difference whatsoever.
Not applicable to your example, but if you are going to use auto parameters you need to be aware of some gotchas:
auto as return type
auto foo(auto a)
Does not mean
// not this
template <class T>
T foo(T a)
The return type will be deduced from the return expression(s) in foo definition, just like any auto return type. It just happens that in your function the return type is deduced to be the same as the parameter type.
Multiple auto parameters
void foo(auto a, auto b)
Is not equivalent to
// not this
template <class T>
void foo(T a, T b)
but with
template <class T, class U>
void foo(T a, U b)
I have a bunch of structs like this with increasing number of members, but consistent member naming:
struct one { int a; };
struct two { int a; int b; };
struct three { int a; int b; int c; };
I also have a templated function which I want to have accept one of these struct's members, splatted:
template <typename T, typename ... ARGS> // T will be one, two, or three
void func(ARGS... args); // This should take 1, 2, or 3, int arguments respectively
I want to be able to call this something like:
two foo;
func<two>(splatter(foo));
Where splatter would somehow split foo so that it would resolve to func<two>(foo.a, foo.b).
I can obviously just expand this inline, without splatter, but the code in which I call func is itself happily templated. I've tried using an initializer_list but I can't figure out how to build one based on template type alone.
Unfortunately my compiler also doesn't support constexpr if to splat a call to func or build an initializer_list. Are there any other options available to me?
As far as I know, what you describe cannot be done using c++. Or if it can, than it is a very complicated solution. The reason is, that you would need to somehow store pointers to class member access functions and then call them properly with your actual object.
However, you get a similar functionality with overloading, which is much easier to implement. For example, you could define a call_func which you overload for your types:
#include <array>
// types
struct one {
int a;
};
struct two {
int a;
int b;
};
struct three {
int a;
int b;
int c;
};
template <class T>
struct more_complex_type {
T a;
T b;
};
// template function
template <typename T, typename... ARGS>
auto func(ARGS... args) {
return std::array<T, sizeof...(args)>{args...};
}
// indirection overload
template <class T>
struct call_func_impl {};
template <>
struct call_func_impl<one> {
auto call(one val) { return func<int>(val.a); }
};
template <>
struct call_func_impl<two> {
auto call(two val) { return func<int>(val.a, val.b); };
};
template <>
struct call_func_impl<three> {
auto call(three val) { return func<int>(val.a, val.b, val.c); };
};
template <class T>
struct call_func_impl<more_complex_type<T>> {
auto call(more_complex_type<T> val) { return func<T>(val.a, val.b); };
};
// syntacting sugar
template <class T>
auto call_func(T val) {
return call_func_impl<T>{}.call(val);
}
// tests
auto test_func() { return func<int>(1, 2, 3, 4, 5); }
auto test_func_of_one() {
auto val = one{};
return call_func(val);
}
auto test_func_of_two() {
auto val = two{};
return call_func(val);
}
auto test_func_of_three() {
auto val = three{};
return call_func(val);
}
auto test_func_of_more_complex_type() {
auto val = more_complex_type<double>{};
return call_func(val);
}
This example uses an overloaded struct template to wrap the function call. This might not be necessary for your case, as you do not have templatized types. You actually could just overload call_func. However, this approach allows you to define the call for more_complex_type which is templatized, as partial function overloading is currently not possible in c++.
hope you guys can help with this:
I have the following function that should return an object Foo, in this case with a specific types:
Foo<int,bool> make_my_foo_object() {
return make_foo(10);
}
in my Foo class I have:
template <class A, class B>
struct Foo {
Foo(A aa): a(aa) {}
Foo(B bb): b(bb) {}
A a;
B b;
};
Then, in my make_foo function I have:
template<typename A, class B>
Foo<A,B> make_foo(A a) {
return Foo<A,B>(a); // this should call the Foo(A) ctor
};
I know this is not possible as there is no way in this simple implementation that B can be infer from the return type of make_foo.
The make_my_foo_object make not much sense in this context, but the whole idea is dealing with template params that cannot be deduced as they are missed.
What I'm trying to avoid is to specify the types in the return make_foo<int, bool>(10); in the make_my_foo_object function.
Do you guys think there is a possible workaround to this? or it's a no-go!
Any help or information will be appreciated.
Thanks.
template<class...Ts>
struct make_something_t {
std::tuple<Ts...> data;
template<class T, std::size_t...Is>
T make(std::index_sequence<Is...>) && {
return T( std::get<Is>(std::move(data))... );
}
template<class T>
operator T()&&{
return std::move(*this).template make<T>(std::make_index_sequence<sizeof...(Ts)>{});
}
};
template<class...Ts>
make_something_t<Ts...> make_something( Ts&&...ts ) {
return {std::forward_as_tuple(std::forward<Ts>(ts)...)};
}
live example.
make_something(args...) doesn't make anything. Instead, you can use it to construct (almost) anything, and it uses args... to do the construction of whatever type you construct from it.
This may not be a great idea, but it deduces the type of object you make from by what object you construct from it.
What I'm trying to avoid is to specify the types in the return make_foo(10); in the make_my_foo_object function.
Something like this probably works for you (minimal, working example in C++14):
template <class A, class B>
struct Foo {
Foo(A aa): a(aa) {}
Foo(B bb): b(bb) {}
A a;
B b;
};
template<typename A, class B>
Foo<A,B> make_foo(A a) {
return Foo<A,B>(a);
}
struct W {
template<typename A, typename B>
operator Foo<A, B>() {
return make_foo<A, B>(10);
}
};
auto make_my_foo_object() {
return W{};
}
int main() {
Foo<int, bool> foo1 = make_my_foo_object();
Foo<int, char> foo2 = make_my_foo_object();
}
Template parameters are deduced by the operator present in W:
template<typename A, typename B>
operator Foo<A, B>() {
return make_foo<A, B>(10);
}
For you tagged it as C++14, auto return type is allowed and it does the rest.
As requested (if I got correctly your request) make_my_foo_object no longer has template parameters, that is it's not a function template.
If your only concern is avoiding repetition of the hardcoded type params, you can just give them names like so:
template <typename A=int, typename B=bool>
Foo<A,B> make_my_foo_object() {
return make_foo<A,B>(10);
}
That is, the decision about what types to use for A and B simply moves from the return type, to the template parameter list.