Below is the sample c++ code that cause error C4346 in vs-2009 pro. I have a
"Record" struct within the Database class, and has a "Retrive(int n)" member
function that return "Record*" type. If I have my implementation code
defined within the class then everything works fine. However if I put it
outside the class I get error C4346. I prefer to put the implementation code
outside the class to keep the code clean. Please help.
Thanks
Jeff
//---------------------------------------------------------------------------
#include <iostream>
#include <string>
using namespace std;
const int Maximum = 100;
//---------------------------------------------------------------------------
// Code-1: Database class definition, has a nested "Record" struct inside
//---------------------------------------------------------------------------
template<typename Object>
class Database {
public:
struct Record {
Object ID;
Record( Object a=Object() ) : ID(a) {}
};
private:
Record items[Maximum];
public:
int Count;
Database() : Count(0) { }
// the following declaration with Code-2 definition will
cause error C4346
Record* Retrieve(const int n);
// however if I replace the code above and those Code-2 with
this the error is gone
// Record* Retrieve(const int n) {
// return &items[n];
// }
void Add(const Record& d) {
if ( Count<Maximum ) items[Count++] = d;
}
};
//---------------------------------------------------------------------------
// Code-2: Retrieve() definition with the return type of "Record".
// Receive the following error when trying to compile
// warning C4346: 'Database<Object>::Record' : dependent name is not a
type
// 1> prefix with 'typename' to indicate a type
// error C2143: syntax error : missing ';' before
'Database<Object>::Retrieve'
// error C4430: missing type specifier - int assumed. Note: C++ does
not support default-int
// fatal error C1903: unable to recover from previous error(s);
stopping compilation
//---------------------------------------------------------------------------
template<typename Object>
Database<Object>::Record*
Database<Object>::Retrieve(const int n) {
return &items[n];
}
//---------------------------------------------------------------------------
// Main Driver
//---------------------------------------------------------------------------
int main(int argc, char* argv[]) {
typedef Database<int>::Record rec;
Database<int> lists;
lists.Add( rec(12) );
lists.Add( rec(13) );
lists.Add( rec(15) );
lists.Add( rec(18) );
lists.Add( rec(17) );
cout << "Record ID\n";
for(int i = 0; i < lists.Count; i++)
cout << lists.Retrieve(i)->ID << endl;
cout << endl;
system("pause");
return 0;
}
//---------------------------------------------------------------------------
// Program Output
//---------------------------------------------------------------------------
Record ID
12
13
15
Press any key to continue . . .
Jeff:
The message tells you what to do:
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...).
BTW, a better place for standard (non .NET) C++ questions is
microsoft.public.vc.language
--
David Wilkinson
Visual C++ MVP
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.
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" <no-r...@effisols.com> wrote in message
news:u8VjCKm...@TK2MSFTNGP02.phx.gbl...
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.
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
"Ben Voigt [C++ MVP]" <bvo...@newsgroup.nospam> wrote in message
news:82051108-F8AD-4832...@microsoft.com...
> 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.