sizeof()

Pages: 12
well, I avoid templates due to the lack of transparency
well, I avoid templates due to the lack of transparency


How about using them instead ? C++ STL is based on templates so if you use them you already is using C++ templatized code. I use them but I never create my own C++ templatized code for reasons I post in other topic.
How about using them instead ? C++ STL is based on templates so if you use them you already is using C++ templatized code. I use them but I never create my own C++ templatized code for reasons I post in other topic.
that is what i do. Furthermore I use boost (great library which I can recommend)
coder777 wrote:

and i for my part wouldn't use what i don't understand.


This is a problem that many C programmers (or any other non-OO language) develop after years of using structured
analysis designs -- there is no line drawn between data and methods there, and as a result, you have to understand
not only what every function does, but how it does it.

Perhaps the whole point of object oriented designs is to separate interface (the what) from implementation (the
how), so that the user need know only what the API is, and not the internal details also.

And later,
coder777 wrote:

that is what i do. Furthermore I use boost (great library which I can recommend)


Which seems quite contrary to your first statement, since surely if you can't understand how ArraySize works, then
you don't understand how most of boost works, yet you still use boost.

coder777 wrote:

I avoid templates due to the lack of transparency


What do you mean by this?
to:helios
thanks for the extra info
rgds
Last edited on
@ jsmith

well, I'm totally into OO. I grew up with OO. heck my first words were OO.

I don't want an insight into the doings of the function.

1
2
3
4
5
template<class T> // What's T?
void function()
{
  ...
}

jsmith wrote:
you have to understand
not only what [every] function does, but how it does it.
<- That applies to the above, no? Since you do need to now what it does with T in order to provide the right thing. That's worse for a class since multiple functions might expect different things from T.

Which seems quite contrary to your first statement, since surely if you can't understand how ArraySize works, then
you don't understand how most of boost works, yet you still use boost.
I don't see any contradiction. It's in the documentation what those classes and functions are doing.

What do you mean by this?

Without (decent) documentation you might not be able to figure out (within an acceptable period of time) what a certain template class or function does even if it looks helpful, that's what I call 'lack of transparency'. So I write templates only when I can't avoid them.


Btw.
I figured out what

1
2
3
4
5
template <typename T,unsigned S>
unsigned ArraySize(const T (&v)[S])
{
  return S;
}

is actually doing.
1. I didn't know that a reference to an (multidimensional) array does exist. This http://heifner.blogspot.com/2005/06/c-reference-to-array.html explains it.
2. 2 template parameter from 1 actual parameter? Ok it works (and i use it right now)
Without (decent) documentation you might not be able to figure out (within an acceptable period of time) what a certain template class or function does even if it looks helpful, that's what I call 'lack of transparency'. So I write templates only when I can't avoid them.


By your definition of "lack of transparency", does that not apply for all functions, templated or not?

<- That applies to the above, no? Since you do need to now what it does with T in order to provide the right thing. That's worse for a class since multiple functions might expect different things from T.


Not necessarily. It depends on how well the function API is thought out. Consider the ArraySize function vs. your original "numof"
function. If you use numof, then yes, absolutely you must know what it does in order to provide the right T. But this is because
the function implementation is bad, for the reasons I stated in a previous reply. But the ArraySize function--if the name isn't
obvious--won't even compile if you pass to it anything other than a fixed length array. As a user of the function, I
don't need to see the body of the function or know how it does what it does; I just have to know that it returns the number of
elements in the array. As the user of the function, if I find myself having to look at the body of the function to see what it does,
this means that a) the name of the function is poor, and b) the documentation of the function is poor -- neither of which are
problems with template programming.
1
2
3
4
5
template <typename T,unsigned S>
unsigned ArraySize(const T (&v)[S])
{
  return S;
}


I wonder, the above argument const is bind to the T correct ? Does that mean ArraySize can only be called for array that has const T where T is a datatype ?

E.g
const int v[3] = {0,0,0};

ArraySize(v) -> gives 3

int v[3] = {0,0,0};

ArraySize(v) -> also gives 3 ? Or it will complain since I am not storing const int in my array ?

Edit:
I try it out and it seems the const T has no effect even at run time I have const int v[3]or int v[3] ? So is the const keyword needed at all ?
Last edited on
@jsmith

ok, I get it. ArraySize is heaven and numof is hell. I just won't discuss this day after day. When templates are better for you then fine. They're certainly apt for libs like boost and stl

@sohguanh

So is the const keyword needed at all ?

Yes, since you can pass both const int v[3] = {0,0,0}; and int v[3] = {0,0,0};, while without const in ArraySize you can only pass the latter. Plus it shows you as the user of ArraySize that you can rely on not changing anything of that const paramter
Last edited on
Yes, since you can pass both const int v[3] = {0,0,0}; and int v[3] = {0,0,0};, while without const in ArraySize you can only pass the latter.


Errr... I just try on my Linux development, without const in the argument, my calling code still can call the ArraySize function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <typename T,unsigned S>
unsigned ArraySize(T (&v)[S]) //remove the const keyword
{
  return S;
};

int main() {
  const int v[3]={0,0,0};
  cout << ArraySize(v) << "\n";

  int v2[3]={0,0,0};
  cout << ArraySize(v2) << "\n";

  return 0;
}
well then, the template thing obviously decides when to put a const and when not. To signal that the parameter will not be changed i'd still write const
There is nothing magic about const and templates. const works the same way for templates as for non-templates.

For instance, this works:

1
2
3
4
5
6
7
8
9
class Foo {
    public:
        void Frobnicate() const;
};

int main() {
    Foo f;
    f.Frobnicate();
}


Frobnicate is a const method, which means it really wants to be called on a const Foo instance, yet
f is clearly not const. The compiler is allowed to implicitly add const qualifiers. So is the case for
ArraySize above, except that it is adding const to all elements of the array.

@coder777:

I only stepped into this thread because you gave an emotional argument for why you'd use numof()
instead of Disch's solution, whereas Disch gave a technical reason why to use his over yours. While
numof() may work for you, if I were in a code review in which I reviewed numof(), I would mark it
as at least a maintainability defect (because it is nothing more than an alias for the sizeof trick and
is susceptible to the same misuse which I documented above... ie, it is zero value-add) if not an
outright major error because of the potential for misue, particularly when a bulletproof solution exists.

I only continued to reply because I felt you continued to give emotional arguments against templates.
Since the purpose here is to provide help to posters asking questions, the best answers are technical
answers.

But I'm not trying to quash opinions; that's what the lounge is for. And besides, sometimes there
aren't answers that are unilaterally "best", such as the debate over source code formatting, tabs or
no tabs, etc. In those cases, the only answers are opinions.
Topic archived. No new replies allowed.
Pages: 12