2

I have a class myClass that is templated, and I have it in mind to use it for two particular types.

The trouble is that whether or not something should be const in myClass depends on whether it is instantiated with the first type (in which pretty much everything is const) or the second type (in which pretty much everything is non-const).

How do I solve this problem? It seems there are two possible approaches.

I could write const in the templated code as if it were for the first type (the one that actually is const), and then somehow "throw away" all those consts once I instantiate with the second type? Is this possible?

The second approach is to not write const at all, and then when I instantiate myClass with the first type, I make the entire object itself const. This seems to make up a bit for the lack of const-correctness in the class implementation itself...

Or maybe I can do something else?

EDIT: Wait, no, the last approach wouldn't work, as I then wouldn't be able to call non-const methods....

4
  • Please show us the actual class. Commented Oct 31, 2018 at 12:17
  • 6
    you may want to take a look at std::conditional and std::is_same. To get a more concrete answer, please consider to add a minimal reproducible example Commented Oct 31, 2018 at 12:18
  • 2
    I'd also add std::is_const Commented Oct 31, 2018 at 12:18
  • 1
    though I would recommend to reconsider if having an implementation with const and one without for two different types is really best realized as a template Commented Oct 31, 2018 at 12:19

2 Answers 2

4

Let's assume you have these two arbitrary types you want to instantiate your template class with, the first of which should trigger constness for your members:

struct RequiresConst
{};

struct OtherStruct
{};

You can then write some convenience templates like this:

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>;

This allows you to naturally spell out what you want:

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

Demo (including test).

Note that this only works for member variables. I'm not aware of a way to make functions const or non-const in a similarly convenient way. But you could write a const and non-const version for each function and enable exactly one of each pair via std::enable_if (or some other SFINAE).

It should also be mentioned that "this member should be const if the template parameter is this exact class" is a pretty odd requirement - not necessarily wrong but smelly. There is probably some specific trait that class has that you should check instead. But maybe your use case really only ever has the template instantiated for those two classes and the above will be sufficient.

Sign up to request clarification or add additional context in comments.

Comments

1

Use a type_traits class.

Start with an empty typetraits class, then specialize it for your first type. Place there all the types you need with the const.

Then specialize it again for your second type, and place there the types without const.

Finally, in your templated class, use the type traits with the template type to select the types you need.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.