Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
4.00/5 (2 votes)
See more:
I have these templates in a header:

C++
//------------------------------------------------------------------------------
template< typename T > T* HLA_newObject( CHighLevelAssemblerBase* self ) __QCMP_THROW
{
    void* addr = self->getZone().zalloc( sizeof(T) );
    return new( addr ) T( self );
}

//------------------------------------------------------------------------------
template< typename T, typename P1 > T* HLA_newObject( CHighLevelAssemblerBase* self, P1 p1 ) __QCMP_THROW
{
    void* addr = self->getZone().zalloc( sizeof(T) );
    return new( addr ) T( self, p1 );                    //Compiler hiccups here!
}

//------------------------------------------------------------------------------
template< typename T, typename P1, typename P2 > T* HLA_newObject( CHighLevelAssemblerBase* self, P1 p1, P2 p2 ) __QCMP_THROW
{
    void* addr = self->getZone().zalloc( sizeof(T) );
    return new( addr ) T( self, p1, p2 );
}


which do placement new of some objects in preallocated memory.

I'm getting this error:

.../HighLevelAssemblerBase.h(55): error C2660: 'operator new' : function does not take 2 arguments

from the VS2010 compiler at the line marked above.
The reference is to this line in the .cpp file:

C++
CEAlign* pAlign = HLA_newObject< CEAlign >( this, m );


despite the following lines from elsewhere in the same module not causing the compiler any issue at all.

C++
CEVariableHint* e = HLA_newObject< CEVariableHint >( this, vdata, hintId, hintValue );

C++
CETarget* target = HLA_newObject< CETarget >( this, label );

C++
CERet* eRet = HLA_newObject< CERet >( this, fn, first, second );


I must be doing something wrong and it's probably pretty obvious but for the life of me I can't see what it could be? Whatever it is it surely isn't an attempt to pass 2 parameters to new.

ADDENDUM:

The only constructor for the 2 parameter case that works, CETarget is:
CETarget( nsArch::CHighLevelAssemblerBase* c, const CLabel& target ) __QCMP_THROW;

For CEAlign, which gives the error, the only constructor is:
CEAlign( nsArch::CHighLevelAssemblerBase* c, Cmp_unsigned__int32 size = 0 ) __QCMP_THROW;


Unless the default parameter is somehow interfering with template matching I don't see how these differ significantly.
Posted
Updated 6-Jun-13 5:19am
v2
Comments
CPallini 6-Jun-13 11:28am    
"Unless the default parameter is somehow interfering with template matching I don't see how these differ significantly"
That's should be easy to verify.
Matthew Faithfull 6-Jun-13 11:37am    
Thanks, I verified it and fortunately VS2010 isn't that badly broken. In this case it was just giving a poor error message due to missing the declaration for placement new.

1 solution

If you have the typical boiler plate code
C++
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

in your code, that could interfere with your template. Just undef it for the code stretch in which you define your templates.
C++
#pragma push_macro ("new")
#undef new

    ... your templates

#pragma pop_macro("new")


AMENDED:

As you said, that should have influenced the three other invocations as well. Silly answer, I admit.

The "new operator does not take two arguments" error message results from the fact that in case of a placement new the "operator new" function is called with two arguments, the address and the requested size. If the compiler complains that it doesn't have an operator new with two arguments that might mean that your class CEAlign overrides the default new operator and thereby covers the 2-argument version. Perhaps that gets you closer to solving the case.
 
Share this answer
 
v2
Comments
Matthew Faithfull 6-Jun-13 10:34am    
Not in this case, no Microsoft boiler plate here. Also I would expect any such issue to hit the 3 variable template as well ::confused::
nv3 6-Jun-13 11:05am    
Admitted, that was a silly answer. See my admendment, which perhaps gets you on the way.
Matthew Faithfull 6-Jun-13 11:22am    
I was looking at something similar, missing constructor overrides but it isn't that or custom new operators which aren't implemented for the classes involved.

However you make an interesting point about placement new taking 2 parameters. Makes me wonder if the placement new declaration is unavailable in one case and not the other but the compiler sort of knows about it anyway so it gives a daft error message. I'll look into that.

...

Yes that's nailed it. Added #include <new> to the .cpp file with the error and hey presto it builds.
Now all I need to do is figure out how on earth the other .cpp files in the module are pulling in <new> implicitly and that one isn't.
I do hate oblique compiler messages that only mean what they say when you know what they mean ;-(
nv3 6-Jun-13 11:35am    
I would try to invoke the template with a little test class that has a two-argument constructor. Just to see if the problem is the number of arguments or the special case of CEAlign.
nv3 6-Jun-13 11:37am    
Ah, I am glad you found it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900