I need to create constructor taking two integers as arguments.
From there I need to call method taking these integers by reference. Inside this method I should dynamically convert integers into char* type (array of digits).
At the end of the constructor I should have two char* arrays instead of initial integers.
I kind of have to do it this way because the other class does the same thing but on structures. And save them into the template attributes.
I'm new to c++ language but my first guess was to use templates. I did a little research on the topic and found out it should work.
I'd love to compile the whole thing myself, but the mess with implementing c++ classes in my head produces quite long list of compile errors.
First question - can this be done using templates?
Second question, because I've already written something by myself:
template <class type> class Addition {
type num_a;
type num_b;
void convert(type, type);
public:
Addition(type, type);
}
template <class type> Addition::Addition(type a, type b) {
convert(&a, &b);
num_a = a;
num_b = b;
}
template <class type> Addition::convert(type *a, type *b) {
int temp_a = a, temp_b = b;
a = char[256], b = char[256];
// converting
}
Is this o.k., or did I do something wrong?
Do you have any suggestions about the way I implement classes in c++?
Why can't I initialize attribute with a value, like:
template <class type> class Addition {
type outcome = 0;
}
And if there's no need to use this keyword in c++, how do I do something like this?:
template <class type> Addition::Foo(type a, type b) {
this->a = a; // a = a;
this->b = b; // b = b;
}
Disclaimer: I cannot judge wheter you really need templates for what you are doing. That would depend on the number of different types that you want your Adddition class template to work with. If you will only use it for int, then perhaps this will introduce unnecessary complexity. You can always refactor later (this would be the Agile approach).
Having said that, if you want to use templates, the usual convention is to write T for a template parameter, and to use type for a nested typedef inside a class template. Using typename or class is a matter of taste, but typename stresses the fact that builtin types can also be passed as arguments. Note however that with template-template parameters you would need to write
template<template<typename> class U> SomeClass { /* your definition */ };
^^^^^ // <-- NOT typename here
which stresses the fact that only class templates can be passed as arguments.
There are a few other nitpicks that one could mention about your code that would make it fail to compile (missing return type in convert() and missing semi-colon in class definition):
template <typename T>
class Addition
{
static const std::size_t N = 256; // are you sure that 256 is all you'll ever need?
T num_a;
T num_b;
void convert(T const*, T const*); // by T const*, not T*
public:
Addition(T const&, T const&); // by T const&, not T
}; // <-- make sure to end class definitions with a semi-colon!
template <typename T>
Addition::Addition(T const& a, T const& b)
{
convert(&a, &b);
num_a = a;
num_b = b;
}
template <typename T>
void Addition::convert(T const* a, T const* b) // <-- use T const* if you don't modify the parameters
^^^^ // <-- you forgot the return type
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only
// converting
}
In C++11 you can even use delegating constructors (supported by latest Visual C++ and of course gcc/Clang) and write
template <typename T>
Addition::Addition(T const& a, T const& b)
:
Addition(&a, &b) // delegate to the other constructor
{}
template <typename T>
Addition::Addition(T const* a, T const* b) // <-- use T const* if you don't modify the parameters
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only
// converting
}
Finally, because template definition have to be in headers anyway, you could even write everything inside the class definition like this:
template <typename T>
class Addition
{
static const std::size_t N = 256; // are you sure that 256 is all you'll ever need?
T num_a;
T num_b;
Addition(T const*, T const*) // by T const*, not T*
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N];
// converting
}
public:
Addition(T const&, T const&) // by T const&, not T
:
Addition(&a, &b) // delegate to the other constructor
{}
}; // <-- make sure to end class definitions with a semi-colon!
This saves you from tediously writing both declarations and definitions of all the member functions. For short and sweet classes (which you should strive for anyway) this is the preferred way of writing templates, but for very long definitions you might want to separate the declaration and definition.
Finally, as was explained by #tacp, you really need to use this->a to disambiguate a class data member from a function parameter. For that reason, people often write data members with a trailing underscore or a m_ prefix.
For your latter questions:
template <class type> class Addition {
//type outcome = 0;
//^^^^you have to call default constructor of type
type outcome = type();
}
It is better to use typename for convention, using class is also OK.
template <class type> Addition::Foo(type a, type b) {
this->a = a; // a = a;
this->b = b; // b = b;
}
If the passed parameter and member has the same name, you need to use this. You cannot do
a =a;
b =b;
since a,b are in local scope, but this->a means class member a.
Since you always want to convert integers to char array, I don't think you really need templates. Unless you would like convert double, float and other types into char* also in the future. I have not looked all the issues, so there may be others remain.
Related
My example below suggests that implicit conversions from non-template types to template types won't work as seamlessly as those only involving non-template types. Is there a way to make them work nonetheless?
Example:
struct point;
template<unsigned d> struct vec {
vec() { }
// ...
};
template<> struct vec<2> {
vec() { }
vec(const point& p) { /* ... */ } // Conversion constructor
// ...
};
struct point {
operator vec<2>() { return vec<2>(/* ... */); } // Conversion operator
};
template<unsigned d> vec<d> foo(vec<d> a, vec<d> b) {
return vec<d>(/* ... */);
}
template<unsigned d1, unsigned d2>
vec<d1 + d2> bar(vec<d1> a, vec<d2> b) {
return vec<d1 + d2>(/* ... */);
}
int main(int argc, char** argv) {
point p1, p2;
vec<2> v2;
vec<3> v3;
foo(v2, p1);
foo(p2, v2);
foo(p1, p2);
bar(v3, p1);
}
Is there a way to let this code auto-convert from point to vec<2>?
I know I can overload foo and bar to allow for point arguments, delegating to the vec implementation using an explicit conversion. But doing this for all parameter combinations will become tedious, particularly for functions with many such parameters. So I'm not interested in solutions where I have to duplicate code for every parameter combination of every function.
It appears that neither the conversion constructor nor the cast operator are sufficient to achieve this. At least my gcc 4.7.1 reports no matching function call, although it does name the desired function in a notice, stating that ‘point’ is not derived from ‘vec<d>’.
There is no direct way to get the conversion from point to vec<2>, because at the time when the function call foo(v1,p1) is processed, a function foo that expects a vec<2> as second argument does not exist yet. It's just a function template, and in order for this to be instantiated to a foo(const vec<2> &,const vec<2> &), a function call with these exact argument types would have to be given.
In order for the code to work, the compiler would have to guess both how to instantiate the template parameters, and what type the point argument to convert to. This is too much in the general case (although in your particular code it appears simple, because there is no other possible way to interpret the intent of the programmer).
In terms of solving this, the only thing I can think of is to create highly templated conversion functions:
template <typename T>
struct make_vec
{ };
template <unsigned d>
struct make_vec<vec<d>>
{
static constexpr unsigned dim = d;
using type = vec<dim>;
static const type &from(const type &v)
{ return v; }
};
template <>
struct make_vec<point>
{
static constexpr unsigned dim = 2;
using type = vec<dim>;
static type from(const point &p)
{ return type(p); }
};
template <typename T>
typename make_vec<typename std::decay<T>::type>::type make_vec_from(T&& arg)
{ return make_vec<typename std::decay<T>::type>::from(std::forward<T>(arg)); }
And then implement the foo and bar functions as general templates (accepting all kinds of types, not only vec<d>, using make_vec defined above to convert the given types to the right kind of vec<d>):
namespace detail {
/* Your original implementation of foo. */
template<unsigned d> vec<d> foo(vec<d>, vec<d>) {
return vec<d>(/* ... */);
}
}
/* Templated version of foo that calls the conversion functions (which do
nothing if the argument is already a vec<d>), and then calls the
foo() function defined above. */
template <typename T, typename... Ts>
typename make_vec<typename std::decay<T>::type>::type foo(T&& arg, Ts&&... args)
{ return detail::foo(make_vec_from(arg),make_vec_from(args)...); }
In the case of bar you also need a way to calculate the return type, which is vec<d1+d2+d3...>. For this, a sum calculator is required, also templated:
template <typename... Ts>
struct dsum {
static constexpr unsigned value = 0;
};
template <typename T, typename... Ts>
struct dsum<T,Ts...> {
static constexpr unsigned value = make_vec<typename std::decay<T>::type>::dim + dsum<Ts...>::value;
};
Then, the return type of bar() is vec<dsum<T,Ts...>::value>.
A fully working example is here: http://liveworkspace.org/code/nZJYu$11
Not exactly simple, but might be worth it if you really have extremely many different combinations of arguments.
I can use function pointer as template argument as the following
template<class R, class T, R (*Fun)(T)>
class MyClass;
Any way to make it is easy as
MyClass<&MyFun> a;
Here is a horrible answer, but I cannot think of a better one.
template<typename R, typename Arg, R(*Fun)(Arg)>
class MyClass {};
template<typename R, typename Arg>
struct MyClassHelper {
template<R(*Fun)(Arg)>
struct Class {
typedef MyClass<R, Arg, Fun> type;
};
};
template<typename R, typename Arg>
MyClassHelper<R, Arg> GetMyClass(R(*Fun)(Arg)); // no impl
void MyFun(int) {}
int main() {
typedef decltype( GetMyClass(&MyFun) ) A;
typedef A::Class<&MyFun> B;
typedef B::type a;
// or, in one line:
decltype( GetMyClass(&MyFun) )::Class<&MyFun>::type b;
}
which is ugly as sin. But at least it extracts the argument types of MyFun without repeating them...
It's not possible exactly as in the question, but yes it's possible if you flex your design a little bit. Let's take an example:
Suppose you have below function:
int foo (int i) { return i; }
Now you want to write:
MyClass<&foo> a; // instead of `Myclass<int, int, &foo> a;
Here how you will achieve it. First change the simple function:
int foo (int i) { return i; }
to encapsulated function object:
struct foo { // <--- function name here
int operator () (int i) { return i; } // <--- function body here
};
Both are almost same (in the case of function object an extra this pointer is passed which doesn't happen in the free function case):
int x = foo(2); // 1st case
int x = foo_(2); // 2nd case where `foo_` is an object of `struct foo`
Now you can use simply as you want!
template<class Func>
class MyClass {...}
MyClass<foo> a;
Here is a working demo.
There's already std::ptr_fun. With C++11, you can use it as
auto a = std::ptr_fun(&MyFun);
Update:
As the other attempts, and non attempts BTW, have shown, isn't it possible with your kind of template, least of all "as easy as" ;-). What you can do however, is sort of reimplement the existing standard template function pattern (std::ptr_fun, std::make_pair and the like) to return the desired type, if your main goal is "as easy as".
Is there a way to make a templated C++ function implicitly convert all pointers to a void*? I'm working on a lightweight Lua binding and I'd like to avoid writing the exact same function for every pointer type when the void* version is all I need.
Declaration:
template<class T>
T GetFromStack(lua_State* L, int index);
Definition:
template<> void* GetFromStack<void*>(lua_State* L, int index)
{
return lua_touserdata(L, index);
}
If I was to call myVariable = GetFromStack<MyStruct*>(L, 0);, the C++ compiler would complain that I haven't defined a function for a MyStruct*. Is it possible to have every pointer type matched to the void* version implicitly?
EDIT:
I see how my question is a bit confusing, I'm not really sure how to word it. I'm attempting to come up with an automatic binding system. This GetFromStack function is called from another templated function:
template<class T_return, class T_param1, class T_param2 >
int LuaFunction(lua_State* L, T_return (*func)(T_param1,T_param2));
which is implemented like this:
template<class T_return, class T_param1, class T_param2 >
int LuaFunction(lua_State* L, T_return (*func)(T_param1,T_param2))
{
T_param1 a = GetFromStack<T_param1>(L, 1);
T_param2 b = GetFromStack<T_param2>(L, 2);
T_return ret = func(a,b);
PushLuaType(L, ret); // <-- This is another templated function
// like GetFromStack that has the same problem
return 1;
}
I then create a Lua version of whatever function I want to expose to Lua with a simple macro:
#define DeclareLuaFunction(function) \
static int ##function##_lua_(lua_State* L) \
{ \
return LuaFunction(L, function); \
}
This works really well so long as I use the predefined types. I have versions of GetFromStack written for all the "basic" types (int, float, etc) and obviously void*. But I don't want to have to write one for every one of my custom type's pointers. When I create a function that uses a MyStruct2, I'd have to write yet another version of GetFromStack that's identical to every other pointer version.
This system would be used like this:
struct MyStruct
{
int a;
float b;
};
int AddToMyStruct(MyStruct* s, int x)
{
int original = s->a;
s->a += x;
return original;
}
DeclareLuaFunction(AddToMyStruct);
Which would then have T_return as an int, T_param1 as a MyStruct* and T_param2 as an integer too. I already have int versions of GetFromStack and PushLuaType, but I don't have MyStruct* versions. With the way it's implemented now, I'd have to write a new version of GetFromStack for every type I come up with, even though every implementation would be the same.
EDIT: Andreas' solution would work if theres a way I can determine if a type is a pointer or not at compile type. If my T_param1 is a MyStruct*, it will be passed as such to GetFromStack, instead of as a MyStruct.
If I understand it correctly, you need to implement the function differently for different types, but the implementation happens to be the same for all pointer types.
If the value was passed as a parameter, you'd use normal function overloading. In this case, you can use enable_if.
template<typename T>
typename std::enable_if<std::is_pointer<T>::value, T>::type
GetFromStack(lua_State* L, int index)
{
return lua_touserdata(L, index);
}
Ok, here's a new try based on your additional info. As has been said before, much of this could be done much easier if you opt to use C++11, but this should work in most older compilers as well.
First you need a way to detect whether your template param T is a pointer, you could either use std::is_pointer<> (which is preferable) or define one yourself like:
template <class T>
struct is_pointer
{
enum {value = false};
};
template <class T>
struct is_pointer<T *>
{
enum {value = true};
};
template <class T>
struct is_pointer<const T *>
{
enum {value = true};
};
Next you need to alter your implementation based on it. To do that we introduce a helper class (or struct as I'm too lazy to write public) which has several specializations, one for each ordinary type and one for pointers:
template <bool ispointer, class T>
struct GetFromStackHelper;
template <>
struct GetFromStackHelper<false, int>
{
static int GetFromStackFun(lua_State *l, int index)
{
return lua_tointeger(l, index);
}
};
// ... add the rest of the built in types here
template <class T>
struct GetFromStackHelper<true, T>
{
static T GetFromStackFun(lua_State *l, int index)
{
return static_cast<T>(lua_touserdata(l, index));
}
};
Finally we tie it together with the GetFromStack function, which now should not have any specializations:
template <class T>
T GetFromStack(lua_State *l, int index)
{
return GetFromStackHelper<is_pointer<T>::value, T>::GetFromStackFun(l, index);
}
Which you could use as:
int i = GetFromStack<int>(luaState, 6);
MyStruct *p = GetFromStack<MyStruct *>(luaState, 5);
I'm not quite sure if this is what you're looking for, but...
How about passing function pointers?
Your compiler's probably going to give you a bunch of warnings, but it should work.
void *GetFromStack(void *p, int index, void * (*func)(void *, int)) {
return func(p, index);
}
void * (*func)(void *, int) is a function pointer to one that takes a void pointer and an int and returns a void pointer, which you supply as the first 2 parameters to GetFromStack. Just use the reference operator & to get a function pointer for the function you want it to call.
I was trying to built atop the thread here: Variable length template arguments list?
to have a default Functor class, this is only of academic interest. My goal is to build a generic Fucntor class: given a class name, method name and argument types(of variable length), it builds a class that has an operator() method which takes variable number of arguments of type specified in template args and takes a pointer and applies the given method. Imagine a class thus:
class MyClass
{
public:
float Fraction( float n, int m)
{
return n/m;
}
int Increment(int n)
{
return n+1;
}
} ;
And a templatized functor class that can be used in any function thus:
int k = FunctorClass<MyClass, Increment, int, int /*return type*/> (3);
assert(k == 4);
float l = FunctorClass<MyClass, Fraction, float, int, float, /*return type*/> (4,3);
assert(l == (4/3));
Can such a functor class be constructed?
Sidenote: Cant use Variadic templates, (building in VS2010, no ... template arguments)
Thanks for the help
This is certainly doable, e.g. Boost bind() uses this approach under the hood. Without variadics you won't get full generality, however, because you will be limited to a fixed number of template arguments and you need to type the implementation for each different number of arguments you want to support. Also, without rvalue references you won't get perfect forwarding.
That said, the way you are trying to use it won't work: when stating the member functions, you can't just name them. You need to obtain the correct member function point using e.g. &MyClass::Increment and &MyClass::Fraction. If the member function is overloaded, you need to disambiguate it.
Since you apparently want to enable the use of this function object for non-static member functions, you also need to provide an object on which the member function is to be called. The most reasonable approach for this is to pass a reference to the object as a constructor argument of the function object class and to store it to be used whenever the function is being called. That is, the use looks somewhat different but it can be simplified with some sort of factory function. Here is a version which adjusts the various things and implements a corresponding function object template:
#include <cassert>
// -----------------------------------------------------------------------------
template <typename T, T> class FunctorClass;
template <typename RC, typename Class,
RC (Class::*Member)()>
class FunctorClass<RC (Class::*)(), Member>
{
public:
FunctorClass(Class& object): object_(&object) {}
RC operator()() const { return (this->object_->*Member)(); }
private:
Class* object_;
};
template <typename RC, typename Class, typename A0,
RC (Class::*Member)(A0)>
class FunctorClass<RC (Class::*)(A0), Member>
{
public:
FunctorClass(Class& object): object_(&object) {}
RC operator()(A0 a0) const { return (this->object_->*Member)(a0); }
private:
Class* object_;
};
template <typename RC, typename Class, typename A0, typename A1,
RC (Class::*Member)(A0, A1)>
class FunctorClass<RC (Class::*)(A0, A1), Member>
{
public:
FunctorClass(Class& object): object_(&object) {}
RC operator()(A0 a0, A1 a1) const { return (this->object_->*Member)(a0, a1); }
private:
Class* object_;
};
// -----------------------------------------------------------------------------
class MyClass
{
public:
int foo() { return 17; }
float Fraction( float n, int m)
{
return n/m;
}
int Increment(int n)
{
return n+1;
}
};
int main()
{
MyClass object;
int i = FunctorClass<int (MyClass::*)(), &MyClass::foo>(object)();
assert(i == 17);
int k = FunctorClass<int (MyClass::*)(int), &MyClass::Increment>(object)(3);
assert(k == 4);
float l = FunctorClass<float (MyClass::*)(float, int), &MyClass::Fraction>(object)(4,3);
assert(l == (4.0f/3));
}
I'm not sure you would need variadics to pull this off. Consider the following interface...
template < typename RETURN_TYPE >
class iFunctor abstract {
public:
virtual RETURN_TYPE operator () ( void ) = 0;
};
Abstract interfaces are not full-blown classes, they can contain a partial implementation such as function signatures and some data members. With the template, you can generalized a return type. But what about the argument list you say?
Note how there is no constructor in the interface. In your concrete class (or derived classes) you can pass the burden of variable argument lists to the constructor, like so...
template < typename TYPE >
class ConcreteFunctor_add : public iFunctor < TYPE > {
private:
int A;
int B;
public:
explicit ConcreteFunctor_add ( const int &a, const int &b ) : A(a), B(b) {};
TYPE operator () ( void ) { return ( A + B ); };
};
You deal with the argument list on a case by case basis through the constructor.
The explicit constructor requires an argument list upon declaration, so you'll get your variable list here. So in practice...
ConcreteFunctor_add < int > addInteger ( 10, 10 );
addInteger();
...and you'd be cool.
We are trying to refactor our code and one of the improvements we want is the following: many functions have many arguments but many of them share a common subset. So, we would like to create a structure that would group them. The problem is that some functions need some of the parameters to be const and some not. Some of these functions must be able to call a subset of these functions supplying this parameter-grouping structure, but under the following restriction: a called function cannot "degrade" the constness of this structure (see the following example). Implementing all required variations of this struct solves the problem but not elegantly. One solution we're working on is to use templates, e.g:
template<class A, class B, class C>
struct my_container
{
A a;
B b;
C c;
};
void foo1(my_container<int, char, float const> & my_cont)
{
}
void foo2(my_container<int const, char, float const> & my_cont)
{
// This should NOT be allowed: we do mind something being const to be treated by the
// called function as non-const.
foo1(my_cont);
}
void foo3(my_container<int, char, float> & my_cont)
{
// This should be allowed: we don't mind something being non-const to be treated by the
// called function as const.
foo2(my_cont);
}
Our problem is that foo2 calls foo1 without the compiler complaining, and we'd like the exact opposite. Is this even possible to implement with templates? Is there any other technique?
Neither should work. Different instantiations of a template are
unreleated types, with no implicit conversions between them. So
my_container<int, char, float const>, my_container<int const, char,
float const> and my_container<int, char, float> are all unrelated
types, with no implicit conversions between them.
It should be possible to work out something using inheritance, using
metaprogramming tricks to determine what you inherit from, but I'm not
sure how, and I suspect that it would be more effort than it's worth.
Without bordering on undefined behavior, this can be achieved with another level of indirection. Add a view class which references the original members. Constness can be added implicitly, but cannot be removed.
template<class A, class B, class C>
struct my_container
{
A a;
B b;
C c;
};
template <class A, class B, class C>
class my_container_view
{
A* a_;
B* b_;
C* c_;
public:
template <class A_, class B_, class C_>
my_container_view(my_container<A_, B_, C_>& source):
a_(&source.a), b_(&source.b), c_(&source.c)
{}
template <class A_, class B_, class C_>
my_container_view(my_container_view<A_, B_, C_>& source):
a_(&source.a()), b_(&source.b()), c_(&source.c())
{}
A& a() const { return *a_; }
B& b() const { return *b_; }
C& c() const { return *c_; }
};
void foo1(my_container_view<int, char, float const> my_cont)
{
my_cont.a() = 10;
my_cont.b() = 'a';
my_cont.c() /*= 3.14*/;
}
void foo2(my_container_view<int const, char, float const> my_cont)
{
my_cont.a() /*= 10*/;
my_cont.b() = 'a';
my_cont.c() /*= 3.14*/;
//foo1(my_cont); //not allowed
}
void foo3(my_container_view<int, char, float> my_cont)
{
my_cont.a() = 10;
my_cont.b() = 'a';
my_cont.c() = 3.14;
t
foo2(my_cont);
}
int main()
{
my_container<int, char, float> mc;
foo1(mc);
foo2(mc);
foo3(mc);
}
(I have my doubts, though, how much this is worth. Normally with classes, either you can modify all its members - and you just don't modify the ones you don't want to -, or you can't modify any. If you want this level of control, you'd rather pass each argument separately - the opposite of what you are doing.)
My solution with a bit meta-programming. Looks pretty ugly and not throughoutly tested, but anyways:
This way, everything should work in general "out of the box"
#include <iostream>
#include <boost/type_traits.hpp>
template<class A, class B, class C>
struct my_container
{
A a;
B b;
C c;
template<typename An, typename Bn, typename Cn>
operator my_container<An,Bn,Cn>& ()
{
/* First, check whether compatible at all */
BOOST_STATIC_ASSERT((boost::is_same<typename boost::remove_cv<A>::type, typename boost::remove_cv<An>::type>::value));
BOOST_STATIC_ASSERT((boost::is_same<typename boost::remove_cv<B>::type, typename boost::remove_cv<Bn>::type>::value));
BOOST_STATIC_ASSERT((boost::is_same<typename boost::remove_cv<C>::type, typename boost::remove_cv<Cn>::type>::value));
/* Enforce const'ness */
BOOST_STATIC_ASSERT( !boost::is_const<A>::value || boost::is_const<An>::value );
BOOST_STATIC_ASSERT( !boost::is_const<B>::value || boost::is_const<Bn>::value );
BOOST_STATIC_ASSERT( !boost::is_const<C>::value || boost::is_const<Cn>::value );
return *reinterpret_cast< my_container<An,Bn,Cn>* >(this);
}
};
void foo1(my_container<int, char, float const> & my_cont)
{
}
void foo2(my_container<int const, char, float const> & my_cont)
{
// This should NOT be allowed: we do mind something being const to be treated by the
// called function as non-const.
//foo1(my_cont); /// BOOST_STATIC_ASSERT fails! Hurray!
}
void foo3(my_container<int, char, float> & my_cont)
{
// This should be allowed: we don't mind something being non-const to be treated by the
// called function as const.
foo2(my_cont); /// No complaints! Hurray!
}
int main(int argc, char* argv[])
{
my_container<int,char,float> foobar;
foo3(foobar);
return 0;
}