如何在模板代码中处理变量const?

时间:2018-10-31 12:14:55

标签: c++ templates const

我有一个模板化的类myClass,我想将它用于两种特定类型。

麻烦的是,const中的某个内容是否应该myClass取决于它是用第一种类型(其中几乎所有内容都是const)实例化还是使用第二种类型实例化类型(几乎所有内容都是非常量)。

如何解决此问题?似乎有两种可能的方法。

我可以在模板代码中编写const,就像它是第一种类型(实际上是const的类型)一样,然后在我用第二种类型实例化后以某种方式“丢弃”所有这些const?这可能吗?

第二种方法是根本不写const,然后当我用第一种类型实例化myClass时,我将使整个对象本身const。这似乎弥补了类实现本身缺乏const正确性的问题。

或者也许我还能做点其他事情?

编辑:等等,不,最后一种方法行不通,因为那样我便无法调用非const方法。...

2 个答案:

答案 0 :(得分:4)

让我们假设您想使用实例化模板类的这两种任意类型,其中第一种应为您的成员触发const ness:

struct RequiresConst
{};

struct OtherStruct
{};

然后您可以编写一些便捷模板,如下所示:

template<class T, bool B>
using conditional_const = typename std::conditional<B, const T, T>::type;

template<class T>
constexpr bool needsConst = std::is_same_v<T, RequiresConst>;

这使您可以自然地拼出所需内容:

template<class T>
struct MyClass
{
    conditional_const<int, needsConst<T>> member;
};

Demo(包括测试)。

请注意,这仅适用于成员变量。我不知道以类似方便的方式制作函数const或非const的方法。但是您可以为每个函数编写一个const和非const版本,并通过std::enable_if(或其他一些SFINAE)启用每个对中的一个。

还应该提到,“如果模板参数是 this 确切类,则此成员应为const”是一个很奇怪的要求-不一定是错误的,但很臭。类中可能有一些特定的特征 ,您应该检查一下。但是也许您的用例实际上只为这两个类实例化了模板,以上内容就足够了。

答案 1 :(得分:1)

使用type_traits类。

从一个空的typetraits类开始,然后将其专门用于您的第一个类型。将所有需要的类型放在const中。

然后再次将其专用于您的第二种类型,并在其中放置没有const的类型。

最后,在模板化类中,将特征类型与模板类型一起使用以选择所需的类型。