0

So I've come across a problem where using function template specialization forces me to write the function in the same namespace as the function template. I cannot do this because some other code requires to define some function template within another specific namespace.

To work-around the namespace issue, I'm trying to use function overloading instead. Furthermore, these functions return value need to be constexpr, so I could not overload using a class reference, so I used a class pointer instead.

So I ended up with this:

template<class T> constexpr auto getName(T* const) { return ""; }

and then I overload them like this:

inline constexpr auto getName(int* const) { return "int"; }

This works fine and allows me to call the correct overload using a nullptr trick like this:

auto name = getName((int* const)nullptr);

My problem is it seems I am unable to overload this when the type is an array. I would like to be able to overload when the type is int[], and return the string "int[]" in that case.

Perhaps there is a better solution to avoid the namespace hell for function template specialization? I know this all stinks but I could not find a better alternative yet.

Thank you!

4
  • 1
    I guess you could use typeid for this specific case. Commented Aug 8, 2018 at 19:32
  • @Rakete1111 I forgot to mention that I cannot use rtti in my case. Commented Aug 8, 2018 at 19:57
  • int(&)[size], with template size. do you need it? Commented Aug 8, 2018 at 20:14
  • @acade unfortunately I can't use class reference in my case. Your solution works fine if I could use references. Commented Aug 8, 2018 at 20:29

1 Answer 1

1

You might use "tag" instead:

template <typename T> struct Tag{};

// template <typename T>
//constexpr auto getName(Tag<T>) { return ""; }

inline constexpr auto getName(Tag<int>) { return "int"; }

inline constexpr auto getName(Tag<int[]>) { return "int[]"; }

template <std::size_t N>
constexpr auto registerName(Tag<int[N]>) { return "int[N]"; }

Demo

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

4 Comments

I do not see how this tag can be used in the real life, without calling code actually knowing it deals with the array - at which point it can simply call a different function instead.
@SergeyA: constexpr auto name = getName((int* const)nullptr); would be constexpr auto name = getName(Tag<int>{}); (where I suppose int would be T in generic code). but indeed getName<T>() would also work but handling getName<std::vector<T>>() would be more problematic.
@Jarod42 I tried your solution but it didn't work for the array type, online test: cpp.sh/9mxh7
@Jarod42 oh nice I didn't think to combine it with the template size constant. It works now, cheers!

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.