简体   繁体   中英

VS2013 has_nothrow_constructor with protected constructor

With VS2013, has_nothrow_constructor and has_nothrow_default_constructor follow the standard more closely. It now states that:

> N3797 20.10.4.3 [meta.unary.prop] says that is_nothrow_default_constructible is equivalent to is_nothrow_constructible. Then it says that is_nothrow_constructible requires is_constructible to be true (and additionally the construction must be "known not to throw any exceptions"). Finally, /6 defines is_constructible in terms of "T t(create()...);" being well-formed, and says that "Access checking is performed as if in a context unrelated to T and any of the Args."

This becomes a bit of a problem when working with a template where I want to basically test the throw capability of a baseclass constructor where it may be protected. For example:

namespace
{
    class CMyBase
    {
    protected:
        CMyBase() throw(){};
    };

    template < typename BlockCopyableClass >
    class TestBlockCopyableBase : public BlockCopyableClass
    {
    protected:
        TestBlockCopyableBase() throw(){}
        ~TestBlockCopyableBase() throw(){}
    private:
        static_assert((std::has_nothrow_constructor< BlockCopyableClass >::value), "BlockCopyableBase classes must have nothrow c-tors");
        static_assert((std::has_nothrow_default_constructor< BlockCopyableClass >::value), "BlockCopyableBase classes must have no throw default c-tors");
    };

    class MyBlockCopyable : public TestBlockCopyableBase< CMyBase >
    {
    };
}

This would work on VS2012/VS2010 but with VS2013 it returns false. Is there a check that doesn't take constructor visibility into the equation?

Additional Comments: There are TONS of CMyBase type classes so modifications to those will be very time consuming (across multiple teams) and the code will still need to compile on VS2010.

Thanks in advance.

Is there a check that doesn't take constructor visibility into the equation?

No, there is not. The fact that it worked in VS2010/2012 was probably a bug.

has_nothrow_constructor and has_nothrow_default_constructor are relics from tr1 (circa 2006). The feature that has was standardized was is_nothrow_constructible and is_nothrow_default_constructible . You should probably use those - but they won't give you different answers; they'll just make your code more portable.

Neither of these deal with non-public constructors. Because the constructors are inaccessible, the checks return false. The type is not default constructible std::is_default_constructible< BlockCopyableClass>::value is false , therefore it cannot be nothrow default constructible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM