Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Invalid Template Argument?

Reply
Thread Tools

Invalid Template Argument?

 
 
Immortal Nephi
Guest
Posts: n/a
 
      08-14-2010
Why do I get compiler error message? It explains that I am not
allowed to create variable in the template parameter, but constant
variable is acceptable.
How can I fix the error?

c:\test_mycode.cpp(24) : error C2975: 'size' : invalid template
argument for 'Test', expected compile-time constant expression
c:\test_template.h(41) : see declaration of 'size'

// Test_Template.h

#if !defined( TEST_TEMPLATE_H )
#define TEST_TEMPLATE_H

enum Type {
Sample_Type1,
Sample_Type2
};

template< Type >
struct Traits {
};

template<>
struct Traits< Sample_Type1 > {
static const int x;
static const int y;
};

template<>
struct Traits< Sample_Type2 > {
static const int x;
static const int y;
};

template< typename T, int size >
class Test {
};

#endif // end macro !defined( TEST_TEMPLATE_H )


// Test_Template.cpp

#include "Test_Template.h"

const int Traits< Sample_Type1 >: = 1;
const int Traits< Sample_Type1 >::y = 2;

const int Traits< Sample_Type2 >: = 10;
const int Traits< Sample_Type2 >::y = 20;

template
class Test< int, Traits< Sample_Type1 >: >;

template
class Test< int, Traits< Sample_Type2 >: >;


// main.cpp

#include "Test_Template.h"

const Type type = Sample_Type1;
const int size = Traits< type >:;

int main() {
// Test< int, size > test;
Test< int, Traits< type >: > test2;

return 0;
}
 
Reply With Quote
 
 
 
 
Immortal Nephi
Guest
Posts: n/a
 
      08-14-2010
On Aug 14, 6:15*pm, Victor Bazarov <(E-Mail Removed)> wrote:
> On 8/14/2010 1:57 PM, Immortal Nephi wrote:
>
> > * *Why do I get compiler error message? *It explains that I am not
> > allowed to create variable in the template parameter, but constant
> > variable is acceptable.
> > * *How can I fix the error?

>
> Try initializing your static integral consts right in their respective
> class definitions (full 'Traits' template specializations), instead of
> later.
>
>
>
>
>
>
>
> > c:\test_mycode.cpp(24) : error C2975: 'size' : invalid template
> > argument for 'Test', expected compile-time constant expression
> > * * * * *c:\test_template.h(41) : see declaration of 'size'

>
> > // Test_Template.h

>
> > #if !defined( TEST_TEMPLATE_H )
> > #define TEST_TEMPLATE_H

>
> > enum Type {
> > * *Sample_Type1,
> > * *Sample_Type2
> > };

>
> > template< *Type>
> > struct Traits {
> > };

>
> > template<>
> > struct Traits< *Sample_Type1> *{
> > * *static const int x;

>
> Try writing
>
> * * *static const int x = 1;
>
> > * *static const int y;
> > };

>
> > template<>
> > struct Traits< *Sample_Type2> *{
> > * *static const int x;

>
> And here (just in case)
>
> * * * *static const int x = 2;
>
>
>
>
>
> > * *static const int y;
> > };

>
> > template< *typename T, int size>
> > class Test {
> > };

>
> > #endif // end macro !defined( TEST_TEMPLATE_H )

>
> > // Test_Template.cpp

>
> > #include "Test_Template.h"

>
> > const int Traits< *Sample_Type1>: = 1;
> > const int Traits< *Sample_Type1>::y = 2;

>
> > const int Traits< *Sample_Type2>: = 10;
> > const int Traits< *Sample_Type2>::y = 20;

>
> > template
> > class Test< *int, Traits< *Sample_Type1>:>;

>
> > template
> > class Test< *int, Traits< *Sample_Type2>:>;

>
> > // main.cpp

>
> > #include "Test_Template.h"

>
> > const Type type = Sample_Type1;
> > const int size = Traits< *type>:;

>
> > int main() {
> > // Test< *int, size> *test;
> > * *Test< *int, Traits< *type>:> *test2;

>
> > * *return 0;
> > }


Not what I wanted, but I found another way. I made my source code to
work without compiler errors. Thanks for your tip.
 
Reply With Quote
 
 
 
 
Francesco S. Carta
Guest
Posts: n/a
 
      08-14-2010
Immortal Nephi <(E-Mail Removed)>, on 14/08/2010 16:38:25, wrote:

> On Aug 14, 6:15 pm, Victor Bazarov<(E-Mail Removed)> wrote:
>> On 8/14/2010 1:57 PM, Immortal Nephi wrote:
>>
>>> Why do I get compiler error message? It explains that I am not
>>> allowed to create variable in the template parameter, but constant
>>> variable is acceptable.
>>> How can I fix the error?

>>
>> Try initializing your static integral consts right in their respective
>> class definitions (full 'Traits' template specializations), instead of
>> later.


<snip original code and several Victor's tips>

> Not what I wanted, but I found another way. I made my source code to
> work without compiler errors. Thanks for your tip.


So post it here to complete the thread, and anybody getting here looking
for a solution to a similar problem will find the working code.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      08-17-2010
On Aug 15, 12:15 am, Victor Bazarov <(E-Mail Removed)> wrote:
> On 8/14/2010 1:57 PM, Immortal Nephi wrote:
>
> > Why do I get compiler error message? It explains that I am not
> > allowed to create variable in the template parameter, but constant
> > variable is acceptable.
> > How can I fix the error?


> Try initializing your static integral consts right in their respective
> class definitions (full 'Traits' template specializations), instead of
> later.


According to the standard, that shouldn't make a difference.
(But it wouldn't surprise me if it did with some compilers.)

--
James Kanze
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      08-17-2010
On 8/17/2010 5:03 AM, James Kanze wrote:
> On Aug 15, 12:15 am, Victor Bazarov<(E-Mail Removed)> wrote:
>> On 8/14/2010 1:57 PM, Immortal Nephi wrote:
>>
>>> Why do I get compiler error message? It explains that I am not
>>> allowed to create variable in the template parameter, but constant
>>> variable is acceptable.
>>> How can I fix the error?

>
>> Try initializing your static integral consts right in their respective
>> class definitions (full 'Traits' template specializations), instead of
>> later.

>
> According to the standard, that shouldn't make a difference.
> (But it wouldn't surprise me if it did with some compilers.)


I don't speak good Standardese, so I usually rely on logic hoping that
it was present in the Committee members' minds when the Standard was
written. So, logically speaking, if I define and initialize a static
classwide const not in the class definition but elsewhere, the compiler
won't have the chance to see that value if I use the static const where
a compile-time constant expression is expected. Example:

----------------------------------- translation unit bar.cpp
struct foo { static const int size; }; // usually from a header

int bar[foo::size]; // huh?
----------------------------------- translation unit foo.cpp
struct foo { static const int size; }; // usually from a header

static const foo::size = 42;
------------------------------------------------------------

OTOH, if I do give the static some value right in the class definition,
the compiler is free to use that value (and not the member) where it
shows up in the code:

----------------------------------- translation unit bar.cpp
struct foo { static const int size = 42; }; // usually from a header

int bar[foo::size]; // success: using the *value* 42
----------------------------------- translation unit foo.cpp
struct foo { static const int size; }; // usually from a header

static const foo::size; // definition - just in case
------------------------------------------------------------

IOW, IMNSHO it *does* make a difference.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      08-17-2010
On Aug 17, 1:40 pm, Victor Bazarov <(E-Mail Removed)> wrote:
> On 8/17/2010 5:03 AM, James Kanze wrote:


> > On Aug 15, 12:15 am, Victor Bazarov<(E-Mail Removed)> wrote:
> >> On 8/14/2010 1:57 PM, Immortal Nephi wrote:


> >>> Why do I get compiler error message? It explains that I am not
> >>> allowed to create variable in the template parameter, but constant
> >>> variable is acceptable.
> >>> How can I fix the error?


> >> Try initializing your static integral consts right in their respective
> >> class definitions (full 'Traits' template specializations), instead of
> >> later.


> > According to the standard, that shouldn't make a difference.
> > (But it wouldn't surprise me if it did with some compilers.)


> I don't speak good Standardese, so I usually rely on logic
> hoping that it was present in the Committee members' minds
> when the Standard was written.


Regretfully, they don't always express themselves in standardese
as clearly as one might wish.

> So, logically speaking, if I define and initialize a static
> classwide const not in the class definition but elsewhere, the
> compiler won't have the chance to see that value if I use the
> static const where a compile-time constant expression is
> expected.


Well, I think I may have misread the original code. I didn't
see that several translation units were involved. But there is
still one problem with your reasoning: I can follow it if
I initialize the constant in another translation unit, or even,
maybe after the actual use. But in the case in question, the
variable was defined and initialized before actual use in the
file. The compiler can easily see the value.

> Example:
>
> ----------------------------------- translation unit bar.cpp
> struct foo { static const int size; }; // usually from a header


> int bar[foo::size]; // huh?


Agreed. Read strictly, the standard requires this to
work, provided foo::size is initialized with an integral
constant expression where ever it happens to be defined. I'm
pretty sure that this was not the intent, however, and no
compiler implements it.

> ----------------------------------- translation unit foo.cpp
> struct foo { static const int size; }; // usually from a header
>
> static const foo::size = 42;


(There's a static too many there. You meant "int const
foo::size = 42;", I'm sure.)

And here:

int bar[foo::size];

is (or should be) legal. The question becomes more interesting
if foo is a template; I think it should still be legal, but
I can imagine some compiler rejecting it, on the grounds that
the definition might have been instantiated in some other
translation unit, rather than this one.

> ------------------------------------------------------------


> OTOH, if I do give the static some value right in the class
> definition, the compiler is free to use that value (and not
> the member) where it shows up in the code:


> ----------------------------------- translation unit bar.cpp
> struct foo { static const int size = 42; }; // usually from a header


> int bar[foo::size]; // success: using the *value* 42
> ----------------------------------- translation unit foo.cpp
> struct foo { static const int size; }; // usually from a header


> static const foo::size; // definition - just in case
> ------------------------------------------------------------


> IOW, IMNSHO it *does* make a difference.


The issue isn't whether you give the static the value in the
class definition. It is whether the definition is visible, so
the compiler can see it. And this issue really only affects
templates:

template<typename T>
struct Foo
{
static int const i;
};

template<typename T>
int Foo<T>::i = 42;

int bar[Foo<int>::i];

--
James Kanze
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Class template problem: template argument 1 is invalid jtravs@gmail.com C++ 1 09-07-2012 07:48 PM
How to use the template member function of a template in the memberfunction of another template class? Peng Yu C++ 3 10-26-2008 03:51 PM
template template arguments: expected a class template, got `Component<T1, T2, T3> gary.bernstein@gmail.com C++ 1 06-08-2007 07:10 AM
Re: A Newbie Question about template template template tom_usenet C++ 0 07-24-2003 12:06 PM
Re: A Newbie Question about template template template Chris Theis C++ 2 07-24-2003 09:42 AM



Advertisments