Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 938225
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T21:36:28+00:00 2026-05-15T21:36:28+00:00

I am working in a very large legacy C++ code base which shall remain

  • 0

I am working in a very large legacy C++ code base which shall remain nameless. Being a legacy code base, it passes raw pointers around all over the place. But we are gradually trying to modernize it and so there are some smart pointer templates as well. These smart pointers (unlike, say, Boost’s scoped_ptr) have an implicit conversion to the raw pointer, so that you can pass one of them into a routine that takes a raw pointer without having to write .get(). A big downside of this is that you can also accidentally use one in a delete statement, and then you have a double free bug, which can be a real pain to track down.

Is there a way to modify the template so that it still has the implicit conversion to the raw pointer, but causes a compile error if used in a delete statement? Like this:

#include <my_scoped_ptr>

struct A {};
extern void f(A*);

struct B
{
    scoped_ptr<A> a;

    B();
    ~B();
};

B::B()
    : a(new A)
{
    f(a); // this should compile
}

B::~B()
{
    delete a; // this should NOT compile
}
  • 1 1 Answer
  • 4 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T21:36:28+00:00Added an answer on May 15, 2026 at 9:36 pm

    The Standard says

    The operand shall have a pointer type, or a class type having a single conversion function (12.3.2) to a pointer type. If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section.

    You can (ab)-use the absence of overload resolution by declaring a const version of the conversion function. On a conforming compiler that’s enough to make it not work anymore with delete:

    struct A {
      operator int*() { return 0; }
      operator int*() const { return 0; }
    };
    
    int main() {
      A a;
      int *p = a; // works
      delete a; // doesn't work
    }
    

    Results in the following

    [js@HOST2 cpp]$ clang++ main1.cpp
    main1.cpp:9:3: error: ambiguous conversion of delete expression of type 'A' to a pointer
      delete a; // doesn't work
      ^      ~
    main1.cpp:2:3: note: candidate function            
      operator int*() { return 0; }
      ^
    main1.cpp:3:3: note: candidate function             
      operator int*() const { return 0; }
      ^
    1 error generated.
    

    On compilers that are less conforming in that regard (EDG/Comeau, GCC) you can make the conversion function a template. delete does not expect a particular type, so this would work:

    template<typename T>
    operator T*() { return /* ... */ }
    

    However, this has the downside that your smartpointer is now convertible to any pointer-type. Although the actual conversion is still typechecked, but this won’t rule out conversions up-front but rather give a compile time error much later. Sadly, SFINAE does not seem to be possible with conversion functions in C++03 🙂 A different way is to return a private nested type pointer from the other function

    struct A {
      operator int*() { return 0; }
    
    private:
      struct nested { };
      operator nested*() { return 0; }
    };
    

    The only problem now is with a conversion to void*, in which case both conversion functions are equally viable. A work-around suggested by @Luther is to return a function pointer type from the other conversion function, which works with both GCC and Comeau and gets rid of the void* problem while having no other problems on the usual conversion paths, unlike the template solution

    struct A {
      operator int*() { return 0; }
    
    private:
      typedef void fty();
      operator fty*() { return 0; }
    };
    

    Notice that these workarounds are only needed for compilers that are not conforming, though.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm working on a very large, data-intensive legacy application. Both the code base &
I'm working with a very large code base and I find it useful to
We're working with some very large config files which contain lots of Unity and
I'm working on a very large project with three phases of source code. Development
I'm working on a project which generates a very large number of sequential text
I'm working on legacy code that looks very similar to this: public class BaseParser
I have a very old, very very large, fully working, C program which plays
I'm working with a large existing codebase with tons of legacy code I can't
I am currently working on a very large legacy MFC MDI application. It has
I am working with a very large text file (500MB+) and the code I

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.