Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to detect construction of a const qualified object? [duplicate]

Assuming two declarations:

const type x;  // case a
type y;        // case b

is it possible to detect case "a" or "b" in type's constructor so that I can execute different operations?

From the standard §12.1/3 we have that:

A constructor can be invoked for a const, volatile or const volatile object. const and volatile semantics (7.1.6.1) are not applied on an object under construction. They come into effect when the constructor for the most derived object (1.8) ends.

therefore this behaves like expected by never being const-qualified at construction (otherwise how could you edit member objects in the body?). So, it seems it's not possible to use type traits on this.

A use case for this would be the following: assuming you are working with an underlying C API that describe specific objects (in a much wider sense), taking hints on their future use along the lines of:

  • STATIC = will not be modified
  • DYNAMIC = can be modified

one could create a wrapper around those C objects and give a STATIC hint on a const construction, and a DYNAMIC hint on a non const construction. Of course const_cast exists and could mess things up, but I'm assuming sane coding here :P.

Am I missing something (considering also C++11 and C++14)?

like image 920
Shoe Avatar asked Mar 09 '14 15:03

Shoe


1 Answers

I dont really know if its worth the struggle and this solution is for sure not perfect as we have to use a helper class Object<T>, but atleast it works very similiar to your requested behaviour:

#include <iostream>
#include <type_traits>

template<typename T>
using Object = typename std::conditional<std::is_const<T>::value, typename T::const_type, typename T::type>::type;

template<bool IsConst>
struct FooHelper;

struct Foo
{
    typedef FooHelper<false> type;
    typedef const FooHelper<true> const_type;

protected:

    Foo(bool isConst)
    {
        if (isConst)
            std::cout << "const" << std::endl;
        else
            std::cout << "non-const" << std::endl;
    }

};

template<>
struct FooHelper<false> : public Foo
{
    FooHelper() : Foo(false) {}
};

template<>
struct FooHelper<true> : public Foo
{
    FooHelper() : Foo(true) {}
};

int main()
{
    Object<Foo> obj;
    Object<const Foo> cobj;
}
like image 180
Sebastian Hoffmann Avatar answered Nov 02 '22 10:11

Sebastian Hoffmann