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 8603167
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T02:15:38+00:00 2026-06-12T02:15:38+00:00

I used the code from Is there a way to test whether a C++

  • 0

I used the code from “Is there a way to test whether a C++ class has a default constructor (other than compiler-provided type traits)?“.

I modified it slightly to work with all my test cases:

template< class T >
class is_default_constructible {
    typedef int yes;
    typedef char no;


    // the second version does not work
#if 1
    template<int x, int y> class is_equal {};
    template<int x> class is_equal<x,x> { typedef void type; };

    template< class U >
    static yes sfinae( typename is_equal< sizeof U(), sizeof U() >::type * );
#else
    template<int x> class is_okay { typedef void type; };

    template< class U >
    static yes sfinae( typename is_okay< sizeof U() >::type * );
#endif

    template< class U >
    static no sfinae( ... );

public:
    enum { value = sizeof( sfinae<T>(0) ) == sizeof(yes) };
};

Why does it work correctly with the two template argument version but not with the normal one (set #if 0)?
Is this a compiler bug? I’m using Visual Studio 2010.

I used the following tests:

BOOST_STATIC_ASSERT( is_default_constructible<int>::value );
BOOST_STATIC_ASSERT( is_default_constructible<bool>::value );
BOOST_STATIC_ASSERT( is_default_constructible<std::string>::value );
BOOST_STATIC_ASSERT( !is_default_constructible<int[100]>::value );

BOOST_STATIC_ASSERT( is_default_constructible<const std::string>::value );

struct NotDefaultConstructible {
    const int x;
    NotDefaultConstructible( int a ) : x(a) {}
};

BOOST_STATIC_ASSERT( !is_default_constructible<NotDefaultConstructible>::value );

struct DefaultConstructible {
    const int x;

    DefaultConstructible() : x(0) {}
};

BOOST_STATIC_ASSERT( is_default_constructible<DefaultConstructible>::value );

I’m really at a loss here:

  1. Two tests are failing with the other version: int[100] and NotDefaultConstructible. All the tests succeed with the two template argument version.
  2. Visual Studio 2010 does not support std::is_default_constructible. However, my question is about why there is any difference in the two implementations and why one works and the other does not.
  • 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-06-12T02:15:39+00:00Added an answer on June 12, 2026 at 2:15 am

    (My answer is greatly informed by DS’s previous answer.)

    First of all, notice that you have class is_okay { typedef void type; }, i.e., type is a private member of is_okay. This means that it’s not actually visible outside the class and therefore

    template< class U >
    static yes sfinae( typename is_equal< sizeof U(), sizeof U() >::type * );
    

    will never succeed. However, SFINAE didn’t originally apply to this situation in C++98; it wasn’t until the resolution to DR 1170 that “access checking [started being] done as part of the substitution process”.[1]

    (Amazingly, Paolo Carlini wrote that blog entry just 10 days ago, so your timing with this question is impeccable. In cases like this, according to Carlini, GCC prior to 4.8 didn’t do access checking during SFINAE at all. So that explains why you didn’t see GCC complaining about the private-ness of type. You’d have to be using a top-of-tree GCC from literally less than two weeks ago, in order to see the correct behavior.)

    Clang (top-of-tree) follows the DR in -std=c++11 mode, but gives the expected error in its default C++03 mode (i.e. Clang doesn’t follow the DR in C++03 mode). This is slightly odd but maybe they do it for backwards compatibility.

    But anyway, you don’t actually want type to be private in the first place. What you meant to write is struct is_equal and struct is_okay.

    With this change, Clang passes all of your test cases. GCC 4.6.1 passes all of your test cases too, except for int[100]. GCC thinks that int[100] is okay, whereas you’re asserting that it’s not okay.

    But another problem with your code is that it doesn’t test what you think it’s testing. The C++ standard, clause 8.5#10, says very clearly: [2]

    An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

    So when you write sizeof U(), you’re not testing if U can be default-initialized; you’re testing if it can be value-initialized!

    …Or are you? At least in some of my test cases, GCC’s error messages indicated that U() was being interpreted as the name of a type — “function returning U” — and that was why int[100] behaved differently. I don’t see how that behavior is valid, but I really don’t understand the syntactic subtleties here.

    If you really mean to test default initialization, you should use something like sizeof *new U everywhere you currently have sizeof U().

    By the way, int[100] is default-initializable, period. The Standard is clear on what it means to default-initialize an array type.

    Finally, I wonder if one cause of wacky behavior in your code is that you’re trying to pass an unadorned 0 (which is of type int) to a function whose set of overloads includes one function taking void * and one taking .... I could totally understand if a compiler picked the wrong one in that case. You’d be better advised to try passing 0 to a function taking int.

    Putting it all together, here’s a version of your code that works perfectly for me (i.e., no assertion-failures) in both ToT Clang and GCC 4.6.1.

    template< class T >
    class is_default_constructible {
        typedef int yes;
        typedef char no;
    
        template<int x> struct is_okay { typedef int type; };
    
        template< class U >
        static yes sfinae( typename is_okay< sizeof (*new U) >::type );
    
        template< class U >
        static no sfinae( ... );
    
    public:
        enum { value = sizeof( sfinae<T>(0) ) == sizeof(yes) };
    };
    
    #if __has_feature(cxx_static_assert)
    #define BOOST_STATIC_ASSERT(x) static_assert(x, "or fail")
    #else
    #define dummy2(line) dummy ## line
    #define dummy(line) dummy2(line)
    #define BOOST_STATIC_ASSERT(x) int dummy(__COUNTER__)[(x) - 1]
    #endif
    
    #include <string>
    
    BOOST_STATIC_ASSERT( !is_default_constructible<int()>::value );
    BOOST_STATIC_ASSERT( is_default_constructible<bool>::value );
    BOOST_STATIC_ASSERT( is_default_constructible<std::string>::value );
    BOOST_STATIC_ASSERT( is_default_constructible<int[100]>::value );
    
    BOOST_STATIC_ASSERT( is_default_constructible<const std::string>::value );
    
    struct NotDefaultConstructible {
        const int x;
        NotDefaultConstructible( int a ) : x(a) {}
    };
    
    BOOST_STATIC_ASSERT( !is_default_constructible<NotDefaultConstructible>::value );
    
    struct DefaultConstructible {
        const int x;
    
        DefaultConstructible() : x(0) {}
    };
    
    BOOST_STATIC_ASSERT( is_default_constructible<DefaultConstructible>::value );
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

The Default code used to LIMIT the results fetched from the MySQL database using
Is there a way to specify what language is being used in the <code>
I used the code from http://www.rgagnon.com/javadetails/java-0580.html to get Motherboard Id, but the result is
I want to get zip code from users current location(Latitude, Longitude), I had used
I have used this code for extracting urls from web page.But in the line
I've used the code in Removing Icon from a WPF window to remove the
I've used this code https://github.com/johannilsson/android-pulltorefresh It all works perfectly apart from one thing, when
The following code is used to fetch logs from app engine for further processing.
I have used the following code to pick up an image from phone's gallery:
I've used the following code, taken from here , to create my own custom

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.