From: Mike on
I'm trying to use shared_ptr and get_deleter in a library I'm
developing, but having problems with syntax errors. Below is a
reduced version that shows the errors I'm getting when building with g+
+-4.1/4.3/4.4:

==================================================================
#include <iostream> // For I/O stream classes.
#include <string> // For string class.
#include <cstdlib> // For EXIT_SUCCESS.
#include <tr1/memory> // For shared_ptr.


// Forward declares/using's of types used in declarations below.
using namespace std;
using std::tr1::shared_ptr;
using std::tr1::get_deleter;


struct Base
{
Base(): i(0) { cout << __PRETTY_FUNCTION__ << endl; }
virtual ~Base() { cout << __PRETTY_FUNCTION__ << endl; }
int i;
};

struct Derived: Base
{
Derived(): num(0.0) { cout << __PRETTY_FUNCTION__ << endl; }
virtual ~Derived() { cout << __PRETTY_FUNCTION__ << endl; }
double num;
};

template <typename T>
struct NoDeleter
{
void operator()(T *p)
{
return;
}
};

template <typename T>
struct Deleter
{
void operator()(T *p)
{
delete p;
}
};

void test_get_deleter()
{
Base localBase;
Derived localDerived;

shared_ptr<Base> localBaseSP(&localBase, NoDeleter());
shared_ptr<Derived> localDerivedSP(&localDerived, NoDeleter());

if (get_deleter<NoDeleter, Base>(localBaseSP))
cout << typeid(*get_deleter<NoDeleter,
Base>(localBaseSP)).name() << endl;
if (get_deleter<NoDeleter, Derived>(localDerivedSP))
cout << typeid(*get_deleter<NoDeleter,
Derived>(localDerivedSP)).name() << endl;

Base *allocBase = new Base;
Derived *allocDerived = new Derived;
Base *allocBase2 = new Derived;

shared_ptr<Base> allocBaseSP(allocBase, Deleter());
shared_ptr<Derived> allocDerivedSP(allocDerived, Deleter());
shared_ptr<Base> allocBaseSP2(allocBase2, Deleter());

if (get_deleter<Deleter, Base>(allocBaseSP))
cout << typeid(*get_deleter<Deleter,
Base>(allocBaseSP)).name() << endl;
if (get_deleter<Deleter, Derived>(allocDerivedSP))
cout << typeid(*get_deleter<Deleter,
Derived>(allocDerivedSP)).name() << endl;
if (get_deleter<Deleter, Base>(allocBaseSP2))
cout << typeid(*get_deleter<Deleter,
Base>(allocBaseSP2)).name() << endl;
}

int main(int argc, char *argv[])
{
test_get_deleter();

return EXIT_SUCCESS;
}
==================================================================

I get the following errors:

g++-4.4 -O0 -g3 -pedantic -Wall -c -fmessage-length=0 -MMD -MP -
MF"get_deleter.d" -MT"get_deleter.d" -o"get_deleter.o" "../
get_deleter.cpp"
.../get_deleter.cpp: In function �void test_get_deleter()�:
.../get_deleter.cpp:50: error: missing template arguments before �(�
token
.../get_deleter.cpp:51: error: missing template arguments before �(�
token
.../get_deleter.cpp:53: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Base>&)�
.../get_deleter.cpp:54: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Base>&)�
.../get_deleter.cpp:55: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Derived>&)�
.../get_deleter.cpp:56: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Derived>&)�
.../get_deleter.cpp:62: error: missing template arguments before �(�
token
.../get_deleter.cpp:63: error: missing template arguments before �(�
token
.../get_deleter.cpp:64: error: missing template arguments before �(�
token
.../get_deleter.cpp:66: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Base>&)�
.../get_deleter.cpp:67: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Base>&)�
.../get_deleter.cpp:68: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Derived>&)�
.../get_deleter.cpp:69: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Derived>&)�
.../get_deleter.cpp:70: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Base>&)�
.../get_deleter.cpp:71: error: no matching function for call to
�get_deleter(std::tr1::shared_ptr<Base>&)�

Is this a compiler bug or "operator error"? I've tried putting angle
brackets on the constructors to try to get rid of the errors like the
ones on lines 62-64 (like so: shared_ptr<Base> allocBaseSP<Base,
Deleter>(allocBase, Deleter()), but then get the error:

../get_deleter.cpp:62: error: expected initializer before �<�
token

which shouldn't be necessary since the compiler should be able to
deduce it (right?).

I added a "using std::tr1::get_deleter;" on line 10 which I don't
think I should need because of argument dependent lookup (right?) to
get rid of the error messages like the ones on lines 66-71 to no
avail.

If operator error, could anyone please tell me what I'm doing wrong or
should I report this as a g++ bug?

Mike


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 12 Apr., 23:41, Mike <mh...(a)bluezoosoftware.com> wrote:
> I'm trying to use shared_ptr and get_deleter in a library I'm
> developing, but having problems with syntax errors. Below is a
> reduced version that shows the errors I'm getting when building with g+
> +-4.1/4.3/4.4:

[..]

> template <typename T>
> struct NoDeleter
> {
> void operator()(T *p)
> {
> return;
> }
> };
>
> template <typename T>
> struct Deleter
> {
> void operator()(T *p)
> {
> delete p;
> }
> };

Note that these are class templates, so you
need to instantiate specializations of them
by providing a corresponding type as in

Deleter<Base>

which you didn't do, instead you wrote

Deleter

Either instantiate them with proper types or
consider to change these templates to
normal classes with a template operator()
overload like this:

struct NoDeleter {
template <typename T>
void operator()(T *p) {}
};

struct Deleter {
template <typename T>
void operator()(T *p) {
delete p;
}
};

With the latter changes your code should compile
as written.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]