我有一个模板化的类myClass
,我想将它用于两种特定类型。
麻烦的是,const
中的某个内容是否应该myClass
取决于它是用第一种类型(其中几乎所有内容都是const
)实例化还是使用第二种类型实例化类型(几乎所有内容都是非常量)。
如何解决此问题?似乎有两种可能的方法。
我可以在模板代码中编写const
,就像它是第一种类型(实际上是const的类型)一样,然后在我用第二种类型实例化后以某种方式“丢弃”所有这些const?这可能吗?
第二种方法是根本不写const,然后当我用第一种类型实例化myClass
时,我将使整个对象本身const
。这似乎弥补了类实现本身缺乏const正确性的问题。
或者也许我还能做点其他事情?
编辑:等等,不,最后一种方法行不通,因为那样我便无法调用非const方法。...
答案 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的类型。
最后,在模板化类中,将特征类型与模板类型一起使用以选择所需的类型。