Определите во время компиляции, если это только для чтения

Можно ли определить, this указатель является константным указателем во время компиляции?
Я хотел бы добиться чего-то вроде этого:

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

Возможно ли что-то подобное?

редактировать

Почему я хочу этого добиться? У меня есть класс, который принимает указатель на таблицу только для чтения. Я хотел бы иметь конструктор, который назначит этот указатель, но только если объект будет только для чтения, потому что редактирование таблицы должно быть запрещено.

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;
};

Если бы static_assert был возможен, приведенный выше код был бы безопасен. Я мог бы использовать так:

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

1

Решение

После того, как вы обновили свой вопрос:

Итак, вы хотите иметь конструктор, который только «возвращает» объект const.

Хотя было предложение по этой функции, оно так и не вошло в стандарт: [N0798]

Простым решением было бы использовать концепцию, описанную Мохамад Эльгави.

Другим вариантом может быть избавление от всего non-const функционирует так, что объект сам по себе const даже если это не совсем так.


СТАРЫЙ ОТВЕТ:

Да, вы можете использовать что-то вроде этого:

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

Тем не менее, я не совсем понимаю, как это может быть полезно, так как любой доступ на запись к этому или его члены также потерпят неудачу во время компиляции, если это const

4

Другие решения

Нет, не напрямую. Вы можете попробовать что-то вроде этого:

#include <memory>

class Foo
{
Foo() = default;
Foo(const Foo&) = delete;

public:
static const Foo* Create()
{
return new Foo();
}
};

int main()
{
std::unique_ptr<const Foo> f(Foo::Create());
//std::unique_ptr<Foo> f(Foo::Create()); // ERROR
return 0;
}
2

По вопросам рекламы [email protected]