By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,847 Members | 2,354 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,847 IT Pros & Developers. It's quick & easy.

templated operators for arrays and pointers

P: n/a
suppose I have class that has templated operator[].
I want to have a few overloads/template specializations for different
types. Basicly, the biggest problem I have is to be able to have this:

const char a[] = "this is passed as an array";
const char *p = "this is passed by the address";
x_class x;
x[a] = .. whatever ..;
x[p] = ..;

then x[a] and x[p] call different overloads. For example inside of the
operator[](...) I want to get the length/size of the passed string. In
case if an array is used it's size is known at compile time and with
pointer I need to calculate the length.

I have a solution, but I'm looking for a better example on how to do
this (Note - it should be templated operator[] and not overloads of
functions or operator())
My solution: (a working example of what I mean)
/////////////

#include <iostream>
#include <cstring>
using namespace std;

class x_class{
template<class T>struct size_of{
static inline size_t value(const T &t){
cout << "dynamic version used" << endl;
return strlen(t);
}
};
template<class T, size_t N>struct size_of<T[N]>{
template<class C>static inline size_t value(const C &){
cout << "static version used" << endl;
return sizeof(C) - 1;
}
};

public:
template<class T>void operator[](const T &t)const{
const char *str = &t[0];
size_t len = size_of<T>::value(t);
(cout << "passed string => \"").write(str,len) << "\"\n\n";
}
};
int main(int,char*[]){
const char a[] = "this is passed as an array";
const char *p = "this is passed by the address";
x_class x;
x[a]; //length known at compile time
x[p]; //length is calculated at runtime
x["some other string"]; //known at compile time
}

////////
PS I'm also interested to have operator[](int) and operator[](int []
and int *)
and there must be no confusion if I use x[0] (eg const char* or int??)
thanks

Jul 29 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
__PPS__ wrote:
[...]
and there must be no confusion if I use x[0] (eg const char* or int??)


There should be no confusion to a C++ programmer: the type of 0 is 'int'.

I'll think a bit more about your other questions.

V
Jul 29 '05 #2

P: n/a
for me it's clear if I call operator[](0), operaor[](size_t) should be
used, but 0 is also a pointer, so there's ambiguos function call if
both operator[](void* or char*) and op[](size_t) are defined.
there's no problem in this case if I do operator[](size_t)0), or
if there's nontemplated version of opearator[](size_t) overload, and
op[] is templated for pointer type (that was my workaround when I had
op[](size_t) and op[](const char*) at the same time and somewhere in
code I had x[0], which gave error (I think both in gcc and vc71); In
that case I rewrote overload for operator[](const char*) as
template<class T>op[](const T*) and it worked)

check by adding to x_class:
void operator()(size_t i){ cout << "operator()(size_t)\n"; }
void operator()(const char *i){ cout << "operator()(const char *)\n";
}
then x[0] is compilation error;
if you change op()(const char*) into:
template<class T>void operator()(const T *i){ cout <<
"operator()(const char *)\n"; }
tjen x[0] calls size_t version without errors

Jul 29 '05 #3

P: n/a
__PPS__ wrote:
for me it's clear if I call operator[](0), operaor[](size_t) should be
used,
Why is it clear? '0' is an "int", not a "size_t". 'int' -> 'size_t'
is a standard integral conversion, which has the same rank as the
conversion from '0' to a pointer (13.3.3.1.1/3).
but 0 is also a pointer,
No, it is NOT. It's a literal of type 'int'.
so there's ambiguos function call if
both operator[](void* or char*) and op[](size_t) are defined.
Yes. Integral conversions and pointer conversions have the same rank.
there's no problem in this case if I do operator[](size_t)0), or
if there's nontemplated version of opearator[](size_t) overload, and
op[] is templated for pointer type (that was my workaround when I had
op[](size_t) and op[](const char*) at the same time and somewhere in
code I had x[0], which gave error (I think both in gcc and vc71); In
that case I rewrote overload for operator[](const char*) as
template<class T>op[](const T*) and it worked)

check by adding to x_class:
void operator()(size_t i){ cout << "operator()(size_t)\n"; }
void operator()(const char *i){ cout << "operator()(const char *)\n";
}
then x[0] is compilation error;
if you change op()(const char*) into:
template<class T>void operator()(const T *i){ cout <<
"operator()(const char *)\n"; }
tjen x[0] calls size_t version without errors


Don't use 'size_t'. Use 'int'.

V
Jul 29 '05 #4

P: n/a
the best solution I found uses enable_if, mpl, and type_traits from
boost:

void operator[](const int i)const{
cout << "[int]\n";
}
void operator[](const std::string &s)const{
cout << "[std::string]\n";
}
template<size_t N>void operator[](const char (&t)[N])const{
cout << "[array of " << N << " elements]\n";
}
template<class T>
typename enable_if<
mpl::and_<is_pointer<T>,
is_same<typename remove_pointer<T>::type,char>
::type operator[](const T t)const{

cout << "[pointer]\n";
}
now it correctly calls array version, pointer, integer or any other
supplied overload (as with string&)

Aug 2 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.