C++17解决方案:
如果您愿意稍微修改一下语法,可以添加
bool modifiable
模板参数到
OnlyLists
,为创建部分规范
modifiable = false
和introcude类模板参数推导(
CTAD
)推断
modifiable
给定构造函数参数:
template<typename T, bool modifiable>
class OnlyLists
{
public:
using ListType = std::list<T>;
OnlyLists(ListType* list) : p_list(list) { }
void modifiesList() {
p_list->clear();
}
size_t viewsList() const {
return p_list->size();
}
private:
ListType* p_list;
};
template<typename T>
class OnlyLists<T, false>
{
public:
using ListType = std::list<T> const;
OnlyLists(ListType* list) : p_list(list) { }
size_t viewsList() const {
return p_list->size();
}
private:
ListType* p_list;
};
// modifiable should be true if and only if the type the pointer points to is non-const
template<typename ListType>
OnlyLists(ListType*) -> OnlyLists<typename ListType::value_type, !std::is_const_v<ListType>>;
int main()
{
std::list<int> non_const_list;
const std::list<int> const_list;
auto a = OnlyLists(&const_list); // a has type OnlyLists<int, false>
a.viewsList();
a.modifiesList(); // compiler error
// Constness is discarded
auto b = OnlyLists(&non_const_list); // b has type OnlyLists<int, true>
b.viewsList();
b.modifiesList();
a = b; // compiler error
decltype(b) c(nullptr);
c = b; // Ok. Uses auto-generated a copy assignment operator
return 0;
}