Type intializing with template

P

paul

When I compile class B shown below, in VC Express 2005, I get error
C2061: syntax error : identifier '{ctor}. Would appreciate any info on
how to avoid the error.

ref class X{
X();
~X();
};

ref class Y{
Y();
~Y();

};

template <class T1,class T2>
ref class A {
public:
A();
~A();
private:
T1^ t1;
T2^ t2;

};

A::A(){
t1 = gcnew T1();
t2 = gcnew T2();

}

ref class B {
static A<X,Y>^ a = gcnew A<X,Y>::A();

};


ptrue
 
A

Antti Keskinen

Hi !

There's a syntax error lurking in your code. The definition of A::A() must
be enclosed into a template declaration, as follows:

template<class T1, class T2>
A<T1,T2>::A()
{
t1 = gcnew T1();
t2 = gcnew T2();
}

Template definitions and declarations cause mysterious syntax errors.
Learning the template syntax exactly is a key priority if you wish to use
it. As you can see, the simple error of lacking the template declaration
caused a head-scratching error, that was only solvable through direct
knowledge on how template class member functions must be defined.

Another (possible) error you have is in the declaration of 'class B'. You're
declaring a static variable, and as far as I remember, the assignment
operation must be done outside the class' scope, in file scope, as follows:

ref class B
{
private: // Default access priviledge. You omitted this, but it's good
policy to always write it.
static A<X,Y>^ a;
};

A<X,Y>^ B::a = gcnew A<X,Y>::A();

Now it should compile and work properly.

-Antti Keskinen
 
C

Carl Daniel [VC++ MVP]

Antti said:
A<X,Y>^ B::a = gcnew A<X,Y>::A();

A<X,Y>^ B::a = gcnew A<X,Y>();

no need for the ::A. Whether the code is legal with the ::A is a matter of
much debate witihin the C++ standard at the moment.

-cd
 
A

Antti Keskinen

Carl Daniel said:
A<X,Y>^ B::a = gcnew A<X,Y>();

no need for the ::A. Whether the code is legal with the ::A is a matter
of much debate witihin the C++ standard at the moment.

-cd

Both work. Considering what is "legal" and what is not - while discovering
that both approaches do precisely the same thing - is a discussion to which
I don't take part. There are certain style issues of course, which are
important and have effect on code readability, but this sort of issue as we
have here is, what I regard to as, "picking on the bones" :)

It just felt a bit difficult of writing "A<X,Y>();" instead of
"A<X,Y>::A();". Perhaps that was because of the template instantation
parameters make the call look somewhat exotic. I don't even wanna fathom a
nested-template static member-function call :D

-Antti Keskinen
 
B

Bo Persson

Antti Keskinen said:
"Carl Daniel [VC++ MVP]"
A<X,Y>^ B::a = gcnew A<X,Y>();

no need for the ::A. Whether the code is legal with the ::A is a
matter of much debate witihin the C++ standard at the moment.

-cd

Both work. Considering what is "legal" and what is not - while
discovering that both approaches do precisely the same thing - is a
discussion to which I don't take part. There are certain style issues
of course, which are important and have effect on code readability,
but this sort of issue as we have here is, what I regard to as,
"picking on the bones" :)

It just felt a bit difficult of writing "A<X,Y>();" instead of
"A<X,Y>::A();".

The A<X,Y>() form is the one intended by the authors of the standard
document.

The form A<X,Y>::A() is probably *also* allowed, but if it really
*should* be is undecided at present. It could be a mistake in the
standard (or not :).


Bo Persson
 
P

paul

Antti,

Thanks for the reply,

The actual code I was working on had the enclosing template declaration
for the constructor. While writing the simplified description of the
problem posted here, I forgot that detail.

ref class B {
private:
static A<X,Y>^ a = gcnew A<X,Y>();
};

The above compiles ok in Visual c++ 2005. While the code below

ref class B {
private:
static A<X,Y>^ a = gcnew A<X,Y>::A();
};

gives C2061: syntax error : identifier '{ctor}

When I tried to follow your advice of using the assignment operation
outside the class' scope, in file scope, I got "static data members of
managed types must be defined within the class definition" error.

Thanks again for I was able to resolve the issue thanks to your, Carl's
and Bo's feedback.


ptrue
 
A

Antti Keskinen

paul said:
When I tried to follow your advice of using the assignment operation
outside the class' scope, in file scope, I got "static data members of
managed types must be defined within the class definition" error.

Hmm..

It seems the C++/CLI standard differs from the C++ Standard here. However,
it's a good thing that the error is clearly stated and easy to fix. If you'd
use your normal C++ skills to create managed static types, this would pose a
problem unless you knew of this quirk.

Does anyone have any idea why Microsoft decided to overrule the C++ Standard
here ? Why aren't the managed static types defined as normal static types
are ?

-Antti Keskinen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top