Search code examples
c++c++11readonlystatic-assert

Determine at compile time if this is read only


Is it possible to determine if this pointer is a const pointer at compile time? I would like to achieve something like this:

class Foo
{
    Foo() 
    { 
        static_assert( is this read only?, "works only on read only objects"); 
    }
}

Is something like that possible?

Edit

Why do I want to achieve this? I have a class that takes a pointer to a read only table. I would like to have a constructor that would assign this pointer but only if the object will be read only, because editing of the table should be forbidden.

class Foo
{
public:
    template <std::size_t N>
    explicit constexpr Foo(const int(&table)[N])
    : m_table(table),
      m_size(N)
    {
    }

    Foo(const Foo& rhs)
    : m_table(new int[rhs.size()]),
      m_size(rhs.size())
    {
         // copy rhs.m_table into m_table
    }


    std::size_t size() const                    { return m_size; }
    const int& row(std::size_t i) const         { assert(m_size > i);  return m_table[i]; }
    int& row(std::size_t i)                     { assert(m_size > i);  return m_table[i]; }

private:
    int* m_table  = nullptr;
    std::size_t m_size  = 0;
};

If the static_assert was possible the above code would be safe. I could use like this:

constexpr int table[10];
constexpr Foo foo(table);  // ok not an error
auto& a = foo.row(0);      // error
const auto& b = foo.row(0) // ok 

Foo bar(foo);
auto& b = bar.row(0);      // ok 

Foo foobar(table)          // static_assert if possible

Solution

  • After you updated your question:

    So what you want to have is a constructor that only "returns" a const object.

    While there has been a proposal for this feature it never made it into the standard: [N0798]

    An easy solution would be to use a concept as described by Mohamad Elghawi.

    Another variant might be to get rid of all non-const functions so that the object is per se const even if it's not really.


    OLD ANSWER:

    Yes, you could use something like this:

    class Foo
    {
    public:
        Foo()
        {
        }
    
        void doSomething()
        {
            static_assert(std::is_const<std::remove_pointer_t<decltype(this)>>::value, "works only on read only objects");
        }
    
        void doSomethingConst() const
        {
            static_assert(std::is_const<std::remove_pointer_t<decltype(this)>>::value, "works only on read only objects");
        }
    
    };
    

    DEMO

    Still I don't really get how this might be useful as any write access to this or it's members will also fail on compile time if this is const...