0

I'm trying to define a class which can be passed an "object allocator" function and takes the template object's operator new() as the default argument. I have the following code:

template<class _Obj>
class Foo
{
private:
    typedef _Obj (_Obj::*fp_alloc_type)();

public:
    Foo(fp_alloc_type t=_Obj::operator new ());

...
};

This gives a comiler error C2039: 'new' : is not a member of 'SomeObj'

Does the compiler not generate a default implementation of 'new' for objects which do not define their own? Am I missing something?

jwalk
  • 1,091
  • 10
  • 25
  • 3
    Yes. The compiler does not generate `operator new` for your class. Where did you get this idea from? – Nawaz Mar 28 '13 at 13:20
  • Then why am I able to call new _Obj()? Is that not _Obj::operator new()? – jwalk Mar 28 '13 at 13:23
  • 2
    @jwalk, nope. It's global new. `::operator new()` – StoryTeller - Unslander Monica Mar 28 '13 at 13:23
  • Does c++ not already have an allocator class? `template < class T > class allocator` – andre Mar 28 '13 at 13:29
  • This previous thread may be helpful: http://stackoverflow.com/questions/1885849/difference-between-new-operator-and-operator-new – Shafik Yaghmour Mar 28 '13 at 13:37
  • @StoryTeller Or not. The compiler follows very specific rules of name lookup here, which are a bit different than those of any other function (since they ignore any namespaces which contain the class). But it's possible to hide the global `operator new`. Of course, if the programmer writes `::new Foo`, then it will use `::operator new()`, regardless. – James Kanze Mar 28 '13 at 13:54

1 Answers1

0

Whatever else it may be, the operator new function is not a non-static member function of any class. Even if you declare and define a class specific operator new, it is considered a static member function; if it takes a single, size_t argument, then a pointer to it would be void* (*ptrToNew)( size_t ). (If it is a placement new, of course, there will be more arguments.)

When you do new Foo, the compiler does a name lookup on operator new first in the scope of Foo (if Foo is a class type), then in the global namespace. (Interestingly enough, the compiler will not look in the namespace in which Foo is declared. Nor does ADL ever apply. An operator new function in a namespace other than the global namespace will never be found.) Unless you've declared an operator new in the class, the global operator new function will be used.

James Kanze
  • 146,674
  • 16
  • 175
  • 326
  • Just as a follow-up, I'm guessing then that there's no standard way to grab a pointer to the object's implementation of the new operator? – jwalk Mar 28 '13 at 14:09
  • @jwalk An object doesn't have an implementation of the `operator new` function. If there is a class specific `operator new`, `void* (*ptrNew)( size_t ) = &Foo::operator new` should work. If you don't know whether there is a class specific `operator new`, you'll need some sort of meta programming to find out. But why do you want it? – James Kanze Mar 28 '13 at 16:18
  • I was interested to write an implementation of an object pool pattern that takes an optional arg in the constructor for allocation method of the objects in the pool. – jwalk Mar 28 '13 at 16:34