T O P I C R E V I E W |
MrDoomMaster |
Posted - Dec 21 2006 : 12:19:23 PM I'm not sure if this problem has been reported or not. I did indeed make an effort to find out myself, but I was unable to find any information regarding this issue.
Suppose I have the following class:
namespace MyCubby
{
template< typename T >
class Foo
{
int MyFunction( T myVar );
};
}
When I use "Create Implementation" on MyFunction, this is what happens:
namespace MyCubby
{
template< typename T >
class Foo
{
int MyFunction( T myVar );
};
int MyCubby::Foo<T>::MyFunction( T myVar )
{
}
}
First of all, this is invalid and will not compile. Second of all, the implementation for this function is placed INSIDE the namespace, which is redundant given that the namespace is used anyway in the definition header for the function.
This is really what it should do:
namespace MyCubby
{
template< typename T >
class Foo
{
int MyFunction( T myVar );
};
}
template< typename T >
int MyCubby::Foo<T>::MyFunction( T myVar )
{
}
1) Notice that template< typename T > is placed above the implementation for the function MyFunction. The implementation of this feature should grab the exact copy of the template declaration used above the class declaration header.
2) Notice secondly that the function implementation is created at FILE SCOPE, not namespace scope. This is my personal preference but obviously isn't required. Creating the implementation inside of namespace scope WITHOUT the redundant MyCubby:: in the function definition header should be an option as well.
Again, given the severity of this problem I can't imagine that you guys aren't aware of it. The severity comes with the fact that by using the feature "Create Implementation" on template function prototypes, the resulting generated definition will NOT compile due to the template definition not appearing before the function definition header.
Apologies if I have duplicated a bug report. |
10 L A T E S T R E P L I E S (Newest First) |
support |
Posted - Jan 17 2007 : 3:45:07 PM Case 4247 is fixed in build 1544. |
feline |
Posted - Dec 27 2006 : 11:45:13 AM quote: Originally posted by Jaeger
I would prefer Create Implementation creating the definition in the namespace without the explicit MyCubby qualification.
This is what I am expecting to happen when this bug is fixed. |
bugfix |
Posted - Dec 22 2006 : 5:40:38 PM ok true, got confused myself now. anyways since vax does make no difference between template classes and template function when using create implementation (uses same autotext) i consider it borked:) adding inline doesn't harm as its just a compiler hint and sure might solve linker problems that may arise. aside of that you re right w/ one definition rule. |
Jaeger |
Posted - Dec 22 2006 : 5:18:43 PM quote: Originally posted by bugfix
you will if you include the same header in more than one cpp file and use the same type for template
fwiw, no idea how precompiled header affect this, w/o them you get linker errors
Not quite.
This is not a function definition but a template. This will not violate ODR because the compiler chooses to instantiate the template when it is first used in a translation unit and the linker resolves the copies into one function in the case the compiler did not decide to inline the calls.
Try it.
// test_me.h
#ifndef TEST_ME_H
#define TEST_ME_H
template< typename T >
struct test_me
{
T go();
};
template< typename T >
T test_me<T>::go()
{
return T(0);
}
#endif //TEST_ME_H
// call_me.cpp
#include "test_me.h"
void call_me()
{
test_me<int>().go();
}
// main.cpp
#include "test_me.h"
void call_me();
void call_me_too()
{
test_me<int>().go();
}
int main()
{
call_me();
call_me_too();
return 0;
} Now if I were to add an explicit specialization to test_me.h such as:
template<>
int test_me<int>::go()
{
return int(1);
}
This would violate ODR unless the inline keyword was added. This explicit specialization does not depend on any template arguments and thus is no longer a template but a function definition.
P.S.
I would prefer Create Implementation creating the definition in the namespace without the explicit MyCubby qualification. i.e.
namespace MyCubby
{
template< typename T >
class Foo
{
int MyFunction( T myVar );
};
template< typename T >
int Foo<T>::MyFunction( T myVar )
{
}
} |
feline |
Posted - Dec 22 2006 : 5:05:05 PM I am staying out of the discussion of what will and will not compile, sometimes the IDE and compiler seems to be a law unto its self
MrDoomMaster I am seeing exactly the same problem here, thank you for the clear description. For now adding another component to the autotext rule seems a bit overkill, but we may consider it in the future.
case=4247 |
bugfix |
Posted - Dec 22 2006 : 2:04:40 PM you will if you include the same header in more than one cpp file and use the same type for template
fwiw, no idea how precompiled header affect this, w/o them you get linker errors |
MrDoomMaster |
Posted - Dec 22 2006 : 1:58:02 PM quote: Originally posted by bugfix
jfyi, if you put template function definition outside of the class you need to add "inline" or you will get multiple symbols error while linking. To sum it up create implementation is completely borked for templates:)
No you don't...
class MyCubby
{
template< typename T >
class Testing
{
void Foo( T var );
};
};
template< typename T >
void MyCubby::Testing<T>::Foo( T var )
{
}
This compiles fine with no linker errors. |
bugfix |
Posted - Dec 22 2006 : 1:27:31 PM jfyi, if you put template function definition outside of the class you need to add "inline" or you will get multiple symbols error while linking. To sum it up create implementation is completely borked for templates:) |
MrDoomMaster |
Posted - Dec 22 2006 : 12:58:50 PM Hi Feline,
I'm using 1543 but this has been a problem since months ago when refactoring first was presented.
I just figured out why this isn't working:
Below is the default "autotext" entry for "Create Implementation":
$SymbolType$ $SymbolContext$( $ParameterList$ ) $MethodQualifier$
{
$end$$MethodBody$
}
Note that there is a newline on the bottom and top of this text.
Here is my current modified version. This version allows me to create a "blank" comment at the top of my created implementation so I can easily fill it in with text:
//===================================================================================================
/**
**
**/
$SymbolType$ $SymbolContext$( $ParameterList$ ) $MethodQualifier$
{
$end$$MethodBody$
}
There is still a newline at the top and now an additional newline at the bottom, for a total of 2 newlines at the bottom
By having this "comment" added at the top, the template header is not created automatically. If I remove the commment, it works as expected.
I'm thinking a good solution to this would be to create a $templateHeader$ variable of some sort that can be manually placed anywhere to provide the user the ability to customize where it is placed. They may want it on the same line as the function header, or above it... Who knows? This would allow them to customize it to their needs.
Having said that, I could do:
//===================================================================================================
/**
**
**/
$TemplateHeader$
$SymbolType$ $SymbolContext$( $ParameterList$ ) $MethodQualifier$
{
$end$$MethodBody$
}
And all would be well! |
feline |
Posted - Dec 22 2006 : 09:02:17 AM Which version of VA are you using? The template function is created correctly for me using VA 1543. The redundant namespace effect is still present in 1543, but this is much less serious.
case=4240 |