473,322 Members | 1,778 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

template deduction of array size


Does anyone know if this is supposed to work ?

template <unsigned N>
int strn( const char str[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}

error: no matching function for call to `strn(const char[5])'
Jul 22 '05 #1
14 3867
> template <unsigned N>
int strn( const char str[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}

error: no matching function for call to `strn(const char[5])'


I think not since neither Comeau nor VC++ 7.1 accept it (results below), but
I must admit I am perplexed as to why. I know that in general a nontype
parameter for a function template can be deduced, but there is clearly
something special about this case. I'll be interested to follow this
thread...

Note that if you change the parameter to bre reference to array, it works...
Maybe this can hint at why the case you presented fails...
Comeau:
"ComeauTest.c", line 11: error: no instance of function template "strn"
matches the
argument list
The argument types that you used are: (const char [5])
std::cout << strn("abcd");

VC++ 7.1:
d:\visual_c++\dot_net\parameter_test\parameter_tes t\main.cpp(11) : error
C2784: 'int strn(const char [N])' : could not deduce template argument for
'const char [N]' from 'const char [5]'
d:\visual_c++\dot_net\parameter_test\parameter_tes t\main.cpp(4) :
see declaration of 'strn'
Jul 22 '05 #2
On 03 Dec 2003 17:27:52 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:

Does anyone know if this is supposed to work ?

template <unsigned N>
int strn( const char str[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}

error: no matching function for call to `strn(const char[5])'


Geez, I read an article in CUJ long time ago that dealt with this very
situation... I think you need to templetize with sizeof().

Hope I inspire you in the right general direction.

Jul 22 '05 #3

"Gianni Mariani" <gi*******@mariani.ws> wrote in message
news:bq********@dispatch.concentric.net...

Does anyone know if this is supposed to work ?

template <unsigned N>
int strn( const char str[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}

error: no matching function for call to `strn(const char[5])'


One other thought: Both the parameter and the argument should decay to a
pointer. (The argument would not if it were reference, but that's not the
case here...). I wonder if this is somehow interfering with the deduction
process...
Jul 22 '05 #4
Dave wrote:
Does anyone know if this is supposed to work ?

template <unsigned N>
int strn( const char str[N] )
{
return N;
}
....

error: no matching function for call to `strn(const char[5])'
... One other thought: Both the parameter and the argument should decay to a
pointer. (The argument would not if it were reference, but that's not the
case here...). I wonder if this is somehow interfering with the deduction
process...


Yes, a reference seems to work, but why does the non reference version
fail ?

template <unsigned N>
int strn( const char ( & str )[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}
OK - I solved my problem.

Jul 22 '05 #5
Gianni Mariani wrote in news:bq********@dispatch.concentric.net:

Does anyone know if this is supposed to work ?

template <unsigned N>
int strn( const char str[N] )
{
return N;
}
This is effectivly:

template < unsigned N >
int strn( char const *str )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}

error: no matching function for call to `strn(const char[5])'


Yup the call needs to be:

std::cout << strn< 5 >( "abcd" );

Where 5 can be any compile time integral constant you want.

template < unsigned N >
unsigned strn( char const (&str)[ N ] )
{
return N;
}

Or get creative:

template < typename T, unsigned N >
unsigned countof( T const (&array)[ N ] )
{
return N;
}

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #6
On Wed, 03 Dec 2003 17:42:53 -0500, Dan W. <da**@raytron-controls.com>
wrote:
On 03 Dec 2003 17:27:52 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:

Does anyone know if this is supposed to work ?

template <unsigned N>
int strn( const char str[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}

error: no matching function for call to `strn(const char[5])'


Geez, I read an article in CUJ long time ago that dealt with this very
situation... I think you need to templetize with sizeof().

Hope I inspire you in the right general direction.


What's wrong with sizeof() itself?
Jul 22 '05 #7
On 03 Dec 2003 18:11:37 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:
Dave wrote:
Does anyone know if this is supposed to work ?

template <unsigned N>
int strn( const char str[N] )
{
return N;
}
...

error: no matching function for call to `strn(const char[5])'

..
One other thought: Both the parameter and the argument should decay to a
pointer. (The argument would not if it were reference, but that's not the
case here...). I wonder if this is somehow interfering with the deduction
process...


Yes, a reference seems to work, but why does the non reference version
fail ?

template <unsigned N>
int strn( const char ( & str )[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}
OK - I solved my problem.


I think that in the case of the array, the number in the brackets is
never passed to the function at runtime; --i.e.: it is equivalent to
passing a pointer, and the number in the brackets is just candy for
your eyes only; whereas a reference is a unique type.

Jul 22 '05 #8
>
I think that in the case of the array, the number in the brackets is
never passed to the function at runtime; --i.e.: it is equivalent to
passing a pointer, and the number in the brackets is just candy for
your eyes only; whereas a reference is a unique type.


Of course! int[5] is not a compile-time type, but a reference to
int[5] IS a type.

Just a C clingon.

Jul 22 '05 #9
> > template <unsigned N>
int strn( const char str[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}

error: no matching function for call to `strn(const char[5])'
I think not since neither Comeau nor VC++ 7.1 accept it (results below),

but I must admit I am perplexed as to why. I know that in general a nontype
parameter for a function template can be deduced, but there is clearly
something special about this case. I'll be interested to follow this
thread...

Note that if you change the parameter to bre reference to array, it works... Maybe this can hint at why the case you presented fails...
Comeau:
"ComeauTest.c", line 11: error: no instance of function template "strn"
matches the
argument list
The argument types that you used are: (const char [5])
std::cout << strn("abcd");

VC++ 7.1:
d:\visual_c++\dot_net\parameter_test\parameter_tes t\main.cpp(11) : error
C2784: 'int strn(const char [N])' : could not deduce template argument for
'const char [N]' from 'const char [5]'
d:\visual_c++\dot_net\parameter_test\parameter_tes t\main.cpp(4) :
see declaration of 'strn'


Has a conclusion been reached on *why* the original code (shown at the top)
fails to compile? Even though we have determined that using a reference
fixes the problem, it is still unclear to me why the original program fails
to compile...
Jul 22 '05 #10
On Wed, 3 Dec 2003 21:06:47 -0700, "Dave" <be***********@yahoo.com>
wrote:
> template <unsigned N>
> int strn( const char str[N] )
> {
> return N;
> }
>
> #include <iostream>
>
> int main()
> {
> std::cout << strn( "abcd" );
> }
>
> error: no matching function for call to `strn(const char[5])'


I think not since neither Comeau nor VC++ 7.1 accept it (results below),

but
I must admit I am perplexed as to why. I know that in general a nontype
parameter for a function template can be deduced, but there is clearly
something special about this case. I'll be interested to follow this
thread...

Note that if you change the parameter to bre reference to array, it

works...
Maybe this can hint at why the case you presented fails...
Comeau:
"ComeauTest.c", line 11: error: no instance of function template "strn"
matches the
argument list
The argument types that you used are: (const char [5])
std::cout << strn("abcd");

VC++ 7.1:
d:\visual_c++\dot_net\parameter_test\parameter_tes t\main.cpp(11) : error
C2784: 'int strn(const char [N])' : could not deduce template argument for
'const char [N]' from 'const char [5]'
d:\visual_c++\dot_net\parameter_test\parameter_tes t\main.cpp(4) :
see declaration of 'strn'


Has a conclusion been reached on *why* the original code (shown at the top)
fails to compile? Even though we have determined that using a reference
fixes the problem, it is still unclear to me why the original program fails
to compile...


Because array notation is an ugly thing carried on from C just for
backward compatibility. The big problem with C arrays is that they do
not carry size information. At run-time, an array is the same thing as
a pointer. At compile time as well, for that matter. The only point at
which the numbers in the brackets are actually used by the compiler is
when you create the array (allocate space). Thus, you were hoping to
select the appropriate template instance of a function *given* the
size of an array, but that array size is NOT given; --i.e.: it doesn't
get carried along with an array. So scope resolution cannot work.
To the compiler, int[5] and int[9] are the same type: int*.

It's as if you open two car garages and say, "odd licence plates go in
garage A, even license plates in garage B; but the cars coming in
have NO license plates, so they can't decide where to go.

References were introduced with C++ and do carry full info with them
at compile time, thus, scope resolution can work its magic.

Cheers!
Jul 22 '05 #11
On 03 Dec 2003 17:27:52 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:

Does anyone know if this is supposed to work ?

template <unsigned N>
int strn( const char str[N] )
{
return N;
}

#include <iostream>

int main()
{
std::cout << strn( "abcd" );
}

error: no matching function for call to `strn(const char[5])'


As others have said, arrays as function parameters decay to pointers.
But you might find these helpful for writing generic code that works
for both containers and arrays:

#include <cstddef>
#include <iterator>

template<class Cont>
std::size_t size(Cont const& c)
{
return c.size();
}

template<class T, std::size_t N>
std::size_t size(T const (&array)[N])
{
return N;
}

template<class T, std::size_t N>
std::size_t size(T (&array)[N])
{
return N;
}

template<class Cont>
typename std::iterator_traits<Cont>::iterator
begin(Cont& c)
{
return c.begin();
}

template<class T, std::size_t N>
T* begin(T (&array)[N])
{
return array;
}

template<class Cont>
typename std::iterator_traits<Cont>::const_iterator
begin(Cont const& c)
{
return c.begin();
}

template<class T, std::size_t N>
T const* begin(T const (&array)[N])
{
return array;
}

template<class Cont>
typename std::iterator_traits<Cont>::iterator
end(Cont& c)
{
return c.end();
}

template<class T, std::size_t N>
T* end(T (&array)[N])
{
return array + N;
}

template<class Cont>
typename std::iterator_traits<Cont>::const_iterator
end(Cont const& c)
{
return c.end();
}

template<class T, std::size_t N>
T const* end(T const (&array)[N])
{
return array + N;
}

(uncompiled code, may need fixing)

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #12
tom_usenet wrote:
On 03 Dec 2003 17:27:52 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:
....
As others have said, arrays as function parameters decay to pointers.
But you might find these helpful for writing generic code that works
for both containers and arrays:


I think I'm going to steal this idea ... :)

Jul 22 '05 #13
On 04 Dec 2003 11:29:00 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:
tom_usenet wrote:
On 03 Dec 2003 17:27:52 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:

...

As others have said, arrays as function parameters decay to pointers.
But you might find these helpful for writing generic code that works
for both containers and arrays:


I think I'm going to steal this idea ... :)


I think it was Dietmar Kuehl's idea originally. His old boost array
utility library (that never got past beta) did something similar I
think.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #14
tom_usenet wrote:
On 04 Dec 2003 11:29:00 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:

tom_usenet wrote:
On 03 Dec 2003 17:27:52 EST, Gianni Mariani <gi*******@mariani.ws>
wrote:


...
As others have said, arrays as function parameters decay to pointers.
But you might find these helpful for writing generic code that works
for both containers and arrays:


I think I'm going to steal this idea ... :)

I think it was Dietmar Kuehl's idea originally. His old boost array
utility library (that never got past beta) did something similar I
think.


I've tried to do somthing similar with the Austria smart pointer
(releasing under GPL soon) library so that iterators can be managed by
smart pointers as well. I probably should have factorized it out into
somthing like this - different problem but same kind of concept.

What intrigues me is that the more you mess with templates, the code
grows in unexpected ways. I'm still getting used to them. There are
significant limitations on templates as defined by the standard, some of
them because the the legacy of C but I can imagine there is far more to
template meta-programming than I can see right now.

The template syntax however is far more obfuscating than I'd like it to
be. It reminds me of some of the visual programming concepts (auto
deduction etc). The thing that worries me is that the body of
programmers that have the fortitude to master templates even at the
minimal levels is far smaller than those than can master C. The success
of a language is directly related to the number of competant
pratitioners and hence my concern. I still run into new compiler
template bugs and that indicates maturity issues.

But, on the other hand, I can write 100% generic code which should work
with far fewer assuptions and hence the satisfaction of creating code
that I theoretically will never need to update as new features are added
to the language. (think upgrades from 16bit to 32bit to 64bit).

.... I rant too much

G
Jul 22 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Raja | last post by:
How to know the buffer size and increase buffer size in c++.
5
by: amparikh | last post by:
Hi all, I was just browsing the archives when I saw one fo the messages posted recently about array size template et al. All along, I have been using the usual template to get the size of the...
13
by: HappyHippy | last post by:
Hi, I'm wondering what you think about this piece of code: #include<iostream> int main() { int size; std::cin >> size;
8
by: Jeff | last post by:
Hello everybody, I'm kind of new to C programming, but here's a little question. Usually, when you have an array of chars, you put a \0 at the end of it to terminate the string. That way, it is...
4
by: terry | last post by:
Hi, Could anyone tell me how to determine the size of array of characters dynamically? For example, : : char *a={"hello","hi","kitty"}; char *b={"orange","apple"};
7
by: arkobose | last post by:
hey everyone! i have this little problem. consider the following declaration: char *array = {"wilson", "string of any size", "etc", "input"}; this is a common data structure used to store...
4
by: Bilgehan.Balban | last post by:
Hi, The following code: #include <stdio.h> // const int const_asize = 10; #define define_asize = 10; int array = {1,2,3,4,5,6,7,8,9,0};
2
by: Harry | last post by:
Good Day To all, When i am declaring a array for e.g char ....it means i am declaring array of 45 characters each of which has a maximum,minimum value limit or range...for example in...
9
by: barcaroller | last post by:
Can variables be used for array size in C++? I know that in the past, I could not do the following: foo (int x) { type arr; } I have recently seen code that does exactly that. Is it right?
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.