Sign in to follow this  

Template idea

This topic is 3466 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

AFAIK, the only advantage of templates in C++ over macros with #define, is that template functions and classes can be put in a scope and don't mess up keywords, while a macro suffers from such problems due to being preprocessed. However, templates are somewhat limiting... only types and integers are variable? I thought of a more general type of templates, where instead of being just a type or integer, the template parameters are arbitrary strings/tokens, but the whole template function or class is still in a scope similar to real C++ templates. Examples:
//nothing new here, except no need to type "typename"
template<T>
T max(const T& a, const T& b)
{
  return a > b ? a : b;
}

//custom name for member variable
template<Name>
struct Vector3
{
  double x;
  double y;
  double Name;
};

Vector3<z> vz;
Vector3<w> vw;
vz.z = 3.0;
vw.w = 3.0;

//using it for values
template<Value, T>
void addSomething(T& i)
{
  i += Value;
}

//e.g.

addSomething<3.0>(d);
addSomething<"hello">(text);

//using it for operators
template<Operator>
int do_operation(int i, int j)
{
  return i Operator j;
}

//e.g.

int x = do_operation<*>(y, z);
int smaller = do_operation<<>(y, z); //smaller than

//using template for custom cast
template<Cast, T, U>
T* cast(U* i)
{
  return Cast<T*>(i);
}

//usage of the above function

struct A,B,C,D;

A* a = new A;
B* b = new B;

C* c = cast<dynamic_cast>(a);
D* d = cast<reinterpret_cast>(a);


Next: converting your template parameter to a quoted string. This is possible by placing a $ character in front of the template parameter (or L$ for wide strings):
//print variable type and value
template<T>
void printTypeAndValue(const T& value)
{
  std::cout << $T << " " << value << std::endl;
}

//usage:

int i = 5;
double d = 6;
typedef int IntTypeDeffed;
IntTypeDeffed t = 7;

printTypeAndValue<long>(i);
printTypeAndValue(d);
printTypeAndValue(t);

/*
output is:

long 5
double 6
IntTypeDeffed 7
*/

Next ability: concatenating template parameters with using "$$"
struct SAA, SAB, SBA, SBB;

template<T1, T1>
void f(const S$$T1$$T2 i)
{
  i.diSomething;
}

int main()
{
  SAA saa;
  f<A, A>(saa);
  SAB sab;
  f<A, B>(sab);
}


So what do you think, could this be useful in a language like C++, or are there problems with the idea?

Share this post


Link to post
Share on other sites
Templates are NOT just beefed-up macros. The two share only a subset of features. You can do stuff with macros thats not possible with templates and vice-versa. Also, you can use them together.

You are wrong with the "only advantage". Templates are turing complete, macros aren't. This means that template metaprogramming is more flexible than macro metaprogramming. I suggest you study Boost.MPL and Boost.Fusion. Also, macros and templates live in different layers; macros operate on a lexical level, templates at the grammar level, which is the reason why debugger can be aware of templates, but not of macros.

What you describe is just a macro system with a different syntax. We don't really need that. We need a much better template syntax for easier metaprogramming. Also, a way to suppress instantiation is sorely needed (will come in form of extern templates in C++0x).

Share this post


Link to post
Share on other sites
//custom name for member variable
template<Name>
struct Vector3
{
double x;
double y;
double Name;
};

Vector3<z> vz;
Vector3<w> vw;
vz.z = 3.0;
vw.w = 3.0;


You are just simply renaming variable. In compiled executable binary names are not present. So this makes little sense to me.

//using it for values
template<Value, T>
void addSomething(T& i)
{
i += Value;
}

//e.g.

addSomething<3.0>(d);
addSomething<"hello">(text);



Why this would be more useful than:


template <class T, class U>
void addSomething(T& i, const U& Value)
{
i += Value;
}
addSomething(d, 3.0);
addSomething(text, "hello");




//using it for operators
template<Operator>
int do_operation(int i, int j)
{
return i Operator j;
}
int x = do_operation<*>(y, z);
int smaller = do_operation<<>(y, z); //smaller than




You can already do that:


#include <functional>

template <class Operator>
int do_operation(int i, int j)
{
return Operator()(i, j);
}

int x = do_operation<std::plus<int> >(y, z);
int smaller = do_operation<std::less<int> >(y, z);



Rest of examples doesn't seem very useful to me.

Share this post


Link to post
Share on other sites
Quote:
AFAIK, the only advantage of templates in C++ over macros with #define


You don't really understand templates.

Quote:
However, templates are somewhat limiting... only types and integers are variable?


They can also be pointers to members, enums, or template specification.

Quote:
I thought of a more general type of templates, where instead of being just a type or integer, the template parameters are arbitrary strings/tokens, but the whole template function or class is still in a scope similar to real C++ templates.

template < typename T, class C, T C::*var >
struct MemberVarPtr {
MemberVarPtr(C & instance)
: ptr(instance)
{}

MemberVarPtr(const MemberVarPtr & other )
: ptr(other.instance)
{}

void print(C * instance) {
std::cout << (instance.*var) << std::endl;
}

MemberVarPtr<T,C,var> & operator=(T rhs)
{
ptr.*var = rhs;
return *this;
}

MemberVarPtr<T,C,var> & operator+=(T rhs)
{
ptr.*var += rhs;
return *this;
}

MemberVarPtr<T,C,var> operator=(const MemberVarPtr & other)
{
return MemberVarPtr(other);
}

private:
C & ptr;
};

struct Vector3
{

double x;
double y;
double Name;
};

int main(int argc, char**argv)
{
Vector3 vec1;
Vector3 vec2;

MemberVarPtr<double, Vector3, &Vector3::Name> ptr_w(vec1);
MemberVarPtr<double, Vector3, &Vector3::Name> ptr_z(vec2);

ptr_w = 3.0;
ptr_z = 4.0;

ptr_w += 3;


return 0;
}


The above concept was basis for the reflection and introspection I used.

Everything else in your examples can be implemented in the same way.

Quote:
//using it for operators
template<Operator>
int do_operation(int i, int j)
{
return i Operator j;
}

Look at <algorithm>. It uses exactly this type of concept.

Quote:
//using template for custom cast
template<Cast, T, U>
T* cast(U* i)
{
return Cast<T*>(i);
}

Since templates are compile-time, there are no instances.


As for everything else:
- Allowing string literal to be passed as template parameter has been requested often, and would have benefits

- You see templates as some syntactic sugar, but completely misunderstand how to use them, or their true capabilities.

Share this post


Link to post
Share on other sites

This topic is 3466 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this