Skip to content

Instantly share code, notes, and snippets.

@alexanderchuranov
Last active July 4, 2024 20:53
Show Gist options
  • Select an option

  • Save alexanderchuranov/00050c2570ffe30a7107e6e4d41567ff to your computer and use it in GitHub Desktop.

Select an option

Save alexanderchuranov/00050c2570ffe30a7107e6e4d41567ff to your computer and use it in GitHub Desktop.
Container exposes methods to mutate the values only if its template parameter is a non-const type
#include <iostream>
#include <type_traits>
// The C++11 implementation.
namespace cxx11 {
template <typename T>
class ConstView {
public:
ConstView() = default;
ConstView(T* p): p_(p) { }
T const& access() const { return *p_; }
protected:
T* p_ = nullptr;
};
template <typename T>
class MutableView
: public ConstView<T> {
public:
MutableView() { }
MutableView(T* p) : ConstView<T>(p) { }
T& access() { return *ConstView<T>::p_; }
};
template <typename T>
class View
: public std::conditional<std::is_const<T>::value,
ConstView<T const>, MutableView<T>>::type {
public:
using base = typename std::conditional<
std::is_const<T>::value,
ConstView<T const>, MutableView<T>>::type;
public:
View() { }
View(T* p) : base(p) { }
};
} // namespace cxx11
// The C++20 implementation.
namespace cxx20 {
template <typename T>
class View {
public:
View() { }
View(T* p) : p_(p) { }
T const& access() const {
return *p_;
}
T& access() requires(!std::is_const<T>::value) {
return *p_;
}
private:
T* p_ = nullptr;
};
} // namespace cxx20
int main() {
int const a = 3;
int b = 5;
{ // Using the C++11 implementation.
using namespace cxx11;
View<int const> va(&a);
View<int> vb(&b);
std::cout << "va.access() = " << va.access() << std::endl;
// ERROR: cannot assign to return value because function 'access'
// returns a const value
//
// va.access() = 33;
std::cout << "vb.access() = " << vb.access() << std::endl;
vb.access() = 11;
std::cout << "vb.access() = " << vb.access() << std::endl;
}
{ // Using the C++20 implementation.
using namespace cxx20;
View va(&a);
View vb(&b);
std::cout << "va.access() = " << va.access() << std::endl;
// ERROR: cannot assign to return value because function 'access'
// returns a const value
//
// va.access() = 33;
std::cout << "vb.access() = " << vb.access() << std::endl;
vb.access() = 11;
std::cout << "vb.access() = " << vb.access() << std::endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment