Discussion:
Please help, how do I fix error C4346 with the code here...
(too old to reply)
Ben Voigt [C++ MVP]
2009-10-26 17:03:27 UTC
Permalink
template<typename Object>
typename Database<Object>::Record* // use typename
Database<Object>::Retrieve(const int n)
{
return &items[n];
}
That said, online Comeau compiles you code as is. (I have never really
understood when you need typename...).
It's because you could have a specialization of Database in which Record
isn't a struct:

template<>
class Database<int> { void Record() { StartRecording(); } };

In the example given, there's no ambiguity, stuff just doesn't work if
Record isn't a type. But this line could either be a function call or a
cast:

Record(x);

This could either be declaration or multiplication (if Record was a
variable):

Record* p;
BTW, a better place for standard (non .NET) C++ questions is
microsoft.public.vc.language
Right. Cross-posting my comments there.
David Wilkinson
2009-10-26 17:34:03 UTC
Permalink
Post by Ben Voigt [C++ MVP]
template<typename Object>
typename Database<Object>::Record* // use typename
Database<Object>::Retrieve(const int n)
{
return &items[n];
}
That said, online Comeau compiles you code as is. (I have never really
understood when you need typename...).
It's because you could have a specialization of Database in which Record
template<>
class Database<int> { void Record() { StartRecording(); } };
In the example given, there's no ambiguity, stuff just doesn't work if
Record isn't a type. But this line could either be a function call or a
Record(x);
This could either be declaration or multiplication (if Record was a
Record* p;
BTW, a better place for standard (non .NET) C++ questions is
microsoft.public.vc.language
Right. Cross-posting my comments there.
Ben:

You think online Comeau is wrong to accept OP's original code? That would be bad
news, because Comeau is my operational definition of whether a piece of code is
correct or not :-).
--
David Wilkinson
Visual C++ MVP
Ben Voigt [C++ MVP]
2009-10-26 17:41:16 UTC
Permalink
Post by David Wilkinson
Post by Ben Voigt [C++ MVP]
template<typename Object>
typename Database<Object>::Record* // use typename
Database<Object>::Retrieve(const int n)
{
return &items[n];
}
That said, online Comeau compiles you code as is. (I have never really
understood when you need typename...).
It's because you could have a specialization of Database in which Record
template<>
class Database<int> { void Record() { StartRecording(); } };
In the example given, there's no ambiguity, stuff just doesn't work if
Record isn't a type. But this line could either be a function call or a
Record(x);
This could either be declaration or multiplication (if Record was a
Record* p;
BTW, a better place for standard (non .NET) C++ questions is
microsoft.public.vc.language
Right. Cross-posting my comments there.
You think online Comeau is wrong to accept OP's original code? That would
be bad news, because Comeau is my operational definition of whether a
piece of code is correct or not :-).
No, I think that in context, none of the non-typename uses could ever be
allowed (multiplication and casting are statements, and not allowed at file
or namespace scope).

And I misread your comment "never understood when you need typename" as "why
you need typename" and explained why it's needed sometimes. I don't see any
good reason that this should be one of those times (the when).

BTW, you did choose "force instantiation of all templates" when using
tryitout, right?
Post by David Wilkinson
--
David Wilkinson
Visual C++ MVP
David Wilkinson
2009-10-26 18:00:41 UTC
Permalink
Post by Ben Voigt [C++ MVP]
Post by David Wilkinson
You think online Comeau is wrong to accept OP's original code? That
would be bad news, because Comeau is my operational definition of
whether a piece of code is correct or not :-).
No, I think that in context, none of the non-typename uses could ever be
allowed (multiplication and casting are statements, and not allowed at
file or namespace scope).
And I misread your comment "never understood when you need typename" as
"why you need typename" and explained why it's needed sometimes. I
don't see any good reason that this should be one of those times (the
when).
BTW, you did choose "force instantiation of all templates" when using
tryitout, right?
Ben:

OK, I misread your post.

Yes, I did use "force instantiation of all templates" (it seems to be the default).

I understand that typename is sometimes needed to avoid ambiguity; it's just
that it's hard to figure out when that might be.
--
David Wilkinson
Visual C++ MVP
Triple-DES
2009-11-10 08:43:53 UTC
Permalink
Post by David Wilkinson
You think online Comeau is wrong to accept OP's original code? That would be bad
news, because Comeau is my operational definition of whether a piece of code is
correct or not :-).
In some instances, Comeau (online) is more lenient with typename than
the Standard. Example:

template <typename T>
struct A
{
struct B { };
B b1_; // ok
A::B b2_; // ill-formed, 'typename' required

};

Comeau online compiles this without a diagnostic.
Igor Tandetnik
2009-11-10 12:51:25 UTC
Permalink
Post by Triple-DES
In some instances, Comeau (online) is more lenient with typename than
template <typename T>
struct A
{
struct B { };
B b1_; // ok
A::B b2_; // ill-formed, 'typename' required
};
Comeau online compiles this without a diagnostic.
typename keyword is not required here. There's an example in 14.6 that shows this exact situation, and no typename keyword:

14.6p2 A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type *unless the applicable name lookup finds a type name* [emphasis mine] or the name is qualified by the keyword typename. [Example:
// no B declared here
class X;
template<class T> class Y {
class Z; // forward declaration of member class
void f() {
X* a1; // declare pointer to X
T* a2; // declare pointer to T
Y* a3; // declare pointer to Y<T>

// ****** This is the part similar to your example.
Z* a4; // declare pointer to Z

typedef typename T::A TA;
TA* a5; // declare pointer to T's A
typename T::A* a6; // declare pointer to T's A
T::A* a7; // T::A is not a type name:
// multiply T::A by a7; ill-formed,
// no visible declaration of a7
B* a8; // B is not a type name:
// multiply B by a8; ill-formed,
// no visible declarations of B and a8
}
};
-end example]
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Triple-DES
2009-11-11 08:21:34 UTC
Permalink
Post by Igor Tandetnik
Post by Triple-DES
In some instances, Comeau (online) is more lenient with typename than
template <typename T>
struct A
{
   struct B { };
   B b1_;    // ok
   A::B b2_; // ill-formed, 'typename' required
};
Comeau online compiles this without a diagnostic.
// no B declared here
class X;
template<class T> class Y {
  class Z; // forward declaration of member class
  void f() {
    X* a1; // declare pointer to X
    T* a2; // declare pointer to T
    Y* a3; // declare pointer to Y<T>
    // ****** This is the part similar to your example.
    Z* a4; // declare pointer to Z
    typedef typename T::A TA;
    TA* a5; // declare pointer to T's A
    typename T::A* a6; // declare pointer to T's A
              // multiply T::A by a7; ill-formed,
                                          // no visible declaration of a7
                                 // multiply B by a8; ill-formed,
                                  // no visible declarations of B and a8
  }};
-end example]
This is not the same situation. In my example, a previously declared
member, B, is referred to _using a qualified name_, in which case the
keyword typename is always required. While

Z* a4; // is well-formed,
Y::Z * a4 // is ill-formed. 'typename' is required here.
Igor Tandetnik
2009-11-11 13:07:01 UTC
Permalink
Post by Triple-DES
This is not the same situation. In my example, a previously declared
member, B, is referred to _using a qualified name_, in which case the
keyword typename is always required.
I suppose you refer to 14.6p6: "...The keyword typename shall always be specified when the member is referred to using a qualified name..." Apparently, Comeau follows DRs 409 and 224, which remove this sentence as well as the rationale for the requirement:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#409
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#224
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Jeff Chang
2009-10-27 21:29:28 UTC
Permalink
Hi David,

Thanks for your help. I will try the non-DotNet group. I also found out
putting the "typename" up front fix the error message. By the way is this
ANSI standard or just VS-2008? My textbook (year 2004) sample didn't have
the "typename" in front.

Besides hope you could give me some advice. Is there any benefit switching
to .Net C++? I am interested in audio-visual programming in the long run.
Should I even consider C# or Java for the sack of productivity?

Thanks
Jeff
Post by Ben Voigt [C++ MVP]
template<typename Object>
typename Database<Object>::Record* // use typename
Database<Object>::Retrieve(const int n)
{
return &items[n];
}
That said, online Comeau compiles you code as is. (I have never really
understood when you need typename...).
It's because you could have a specialization of Database in which Record
template<>
class Database<int> { void Record() { StartRecording(); } };
In the example given, there's no ambiguity, stuff just doesn't work if
Record isn't a type. But this line could either be a function call or a
Record(x);
This could either be declaration or multiplication (if Record was a
Record* p;
BTW, a better place for standard (non .NET) C++ questions is
microsoft.public.vc.language
Right. Cross-posting my comments there.
Ulrich Eckhardt
2009-10-28 07:49:03 UTC
Permalink
Post by Jeff Chang
Thanks for your help. I will try the non-DotNet group. I also found out
putting the "typename" up front fix the error message. By the way is this
ANSI standard or just VS-2008?
It's part of the ISO standard.
Post by Jeff Chang
My textbook (year 2004) sample didn't have the "typename" in front.
Many compilers at that time still let it slip. However, there are also many
bad textbooks out there.

Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
Ulrich Eckhardt
2009-10-28 07:49:03 UTC
Permalink
Post by Jeff Chang
Thanks for your help. I will try the non-DotNet group. I also found out
putting the "typename" up front fix the error message. By the way is this
ANSI standard or just VS-2008?
It's part of the ISO standard.
Post by Jeff Chang
My textbook (year 2004) sample didn't have the "typename" in front.
Many compilers at that time still let it slip. However, there are also many
bad textbooks out there.

Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
Giovanni Dicanio
2009-11-08 18:56:47 UTC
Permalink
Post by Jeff Chang
Besides hope you could give me some advice. Is there any benefit switching
to .Net C++? I am interested in audio-visual programming in the long run.
Should I even consider C# or Java for the sack of productivity?
With '.Net C++' you mean C++/CLI, don't you?
I think that C++/CLI is good as a bridging layer between native code and
managed code.
e.g. if you have some native C++ library and you want to use that from .NET
languages like C#, you could develop a thin C++/CLI layer to connect the
native C++ platform with the .NET managed platform.
But my impression is that C++/CLI is not a first class .NET language; for
example: if you want to build GUIs with WPF, you can use C# or VB.NET, but
not C++/CLI (at least, this is my understanding).
And I think that ASP.NET does not support C++/CLI (only C# or VB.NET).
So, if you want to build something in .NET, I would suggest to consider C#
or VB.NET (if you come from C++, you would prefer C#, because its syntax
looks more natural than VB.NET for someone with a C++/Java background).

About productivity, yes C# offers high productivity to the programmer.
But if you want something that is small and fast, C++ is the way to go.

Giovanni
Scot Brennecke
2009-11-09 05:56:16 UTC
Permalink
Post by Giovanni Dicanio
Post by Jeff Chang
Besides hope you could give me some advice. Is there any benefit
switching to .Net C++? I am interested in audio-visual programming in
the long run. Should I even consider C# or Java for the sack of
productivity?
With '.Net C++' you mean C++/CLI, don't you?
I think that C++/CLI is good as a bridging layer between native code and
managed code.
e.g. if you have some native C++ library and you want to use that from
.NET languages like C#, you could develop a thin C++/CLI layer to
connect the native C++ platform with the .NET managed platform.
But my impression is that C++/CLI is not a first class .NET language;
for example: if you want to build GUIs with WPF, you can use C# or
VB.NET, but not C++/CLI (at least, this is my understanding).
And I think that ASP.NET does not support C++/CLI (only C# or VB.NET).
So, if you want to build something in .NET, I would suggest to consider
C# or VB.NET (if you come from C++, you would prefer C#, because its
syntax looks more natural than VB.NET for someone with a C++/Java
background).
About productivity, yes C# offers high productivity to the programmer.
But if you want something that is small and fast, C++ is the way to go.
Giovanni
Well, C++/CLI will compile to MSIL just as any other .NET language, so
once it's compiled, it is supported anywhere any .NET assembly might be.
However, I agree that C# would almost always be the better choice for
developing a WinForms or WPF application. You CAN do it with C++/CLI,
but the syntax and IDE just aren't as friendly.
Jeff Chang
2009-10-27 21:29:28 UTC
Permalink
Hi David,

Thanks for your help. I will try the non-DotNet group. I also found out
putting the "typename" up front fix the error message. By the way is this
ANSI standard or just VS-2008? My textbook (year 2004) sample didn't have
the "typename" in front.

Besides hope you could give me some advice. Is there any benefit switching
to .Net C++? I am interested in audio-visual programming in the long run.
Should I even consider C# or Java for the sack of productivity?

Thanks
Jeff
Post by Ben Voigt [C++ MVP]
template<typename Object>
typename Database<Object>::Record* // use typename
Database<Object>::Retrieve(const int n)
{
return &items[n];
}
That said, online Comeau compiles you code as is. (I have never really
understood when you need typename...).
It's because you could have a specialization of Database in which Record
template<>
class Database<int> { void Record() { StartRecording(); } };
In the example given, there's no ambiguity, stuff just doesn't work if
Record isn't a type. But this line could either be a function call or a
Record(x);
This could either be declaration or multiplication (if Record was a
Record* p;
BTW, a better place for standard (non .NET) C++ questions is
microsoft.public.vc.language
Right. Cross-posting my comments there.
Continue reading on narkive:
Loading...