Можно ли определить, 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
После того, как вы обновили свой вопрос:
Итак, вы хотите иметь конструктор, который только «возвращает» объект 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");
}
};
Тем не менее, я не совсем понимаю, как это может быть полезно, так как любой доступ на запись к этому или его члены также потерпят неудачу во время компиляции, если это const
Нет, не напрямую. Вы можете попробовать что-то вроде этого:
#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;
}