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

  • SEARCH
  • Home
  • 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 6387699
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T03:11:06+00:00 2026-05-25T03:11:06+00:00

Consider the following: class A { private: A() {} public: A(int x = 0)

  • 0

Consider the following:

class A
{
private:
    A() {}
public:
    A(int x = 0) {}
};


int main()
{
    A a(1);
    return 0;
}

I have two constructors, one is a default and the other one is converting constructor with a default argument. When I try to compile the code, I expected an ambiguity error, but the compiler doesn’t produce one.

Even when I don’t create an instance of A, it doesn’t produce an ambiguity error either.

int main()
{
    return 0;
}

Why is that?

  • 1 1 Answer
  • 0 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-25T03:11:06+00:00Added an answer on May 25, 2026 at 3:11 am

    Your code compiles because there is no ambiguity. You created a class with two constructors, one which always takes 0 arguments, and one which always takes one argument, an int. You then unambiguously called the constructor taking an int value. That this int has a default value does not matter, it is still a completely different signature. That the constructors are potentially ambiguous doesn’t matter, the compiler only complains when a particular call is actually ambiguous.

    When you create an instance of A with no arguments, it doesn’t know which constructor you want to call: the default constructor, or the constructor taking an int with a parameter value of 0. In this case it would be nice if C++ notices that the private constructor is ineligible, but that is not always possible.

    This behavior ends up being useful in some circumstances (e.g. if you have a few overloads involving templates, some of which will overlap if given the right types), though for simple cases like this, I would just make the single constructor with the default argument (preferably marked explicit unless you have a really really good reason to leave it implicit, and then I would second guess that reason just to be sure!)

    — EDIT —

    Let’s have some fun with this and try to explore further what is happening.

    // A.h
    class A
    {
    public:
        A(); // declare that somewhere out there, there exists a constructor that takes no args.  Note that actually figuring out where this constructor is defined is the linker's job
        A(int x = 10); // declare that somewhere out there, there exists a constructor that take one arg, an integer. Figuring out where it is defined is still the linker's job. (this line does _not_ declare two constructors.)
    
        int x;
    };
    
    // A.cpp
    #include "A.h"
    
    A::A() { ... } // OK, provide a definition for A::A()
    A::A(int x) { ... } // OK, provide a definition for A::A(int) -- but wait, where is our default param??
    
    // Foo.cpp
    #include "A.h"
    
    void Foo()
    {
        A a1(24); // perfectly fine
        A a2; // Ambigious!
    }
    
    // Bar.cpp
    class A // What's going on? We are redefining A?!?!
    {
    public:
        A();
        A(int x); // this definition doesn't have a default param!
        int x;
    };
    
    void Bar()
    {
        A a; // This works! The default constructor is called!
    }
    
    // Baz.cpp
    class A // What's going on? We are redefining A again?!?!
    {
    public:
        //A(); // no default constructor!
        A(int x = 42); // this definition has a default param again, but wait, it's different!
        int x;
    };
    
    void Baz()
    {
        A a; // This works! A::A(int) is call! (but with what parameter?)
    }
    

    Note that we are taking advantage of the fact that the compiler doesn’t know about headers; by the time it looks at a .cpp file, the preprocessor has already substituted #includes with the body of the header. I am playing at being my own preprocessor, doing some dangerous things like providing multiple, different definitions of a class. Later on, one of the linker’s jobs is to throw out all but one of these definitions. If they do not align up in the exact right way, all kinds of bad things will happen, as you will be in the twilight zone of undefined behavior.

    Note that I was careful to provide the exact same layout for my class in every compilation unit; every definition has exactly 1 int and 0 virtual methods. Note that I did not introduce any extra methods (though that might work; still doing things like this should be looked on with great suspicion), the only thing that changed were some non-virtual member functions (well constructors really) and then only to remove the default constructor. Changing and removing the default value changed nothing about the definition of A::A(int).

    I don’t have a copy of the spec on me, so I can’t say if my careful changes fall under undefined behavior or implementation specific behavior, but I would treat it as such for production code and avoid leveraging such tricks.

    And the ultimate answer to what argument is used inside of Baz is,…. 42!

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

Sidebar

Related Questions

Consider you have the following class public class OuterClass { ... private static class
Consider the following code: class Rectangle { public: // Constructors Rectangle(){ init(0,0); } Rectangle(int
Consider the following class: public class MyIntSet { private List<int> _list = new List<int>();
Consider the following nested type: public class Book { private class Chapter { }
Please consider the following java source: package com.stackoverflow; public class CondSpeed { private static
Consider following class class test { public: test(int x){ cout<< test \n; } };
Consider the following class: class Something : ISomething { public void DoesSomething(int x) {
Consider the following class public class Class1 { public int A { get; set;
Consider the following situation: class MyFoo { public: MyFoo(); ~MyFoo(); void doSomething(void); private: unsigned
Consider a following chunk of service: public class ProductService : IProductService { private IProductRepository

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.