0

Dan's answer to this question: Is There Anything Like a Templatized Case-Statement takes a DefaultType template parameter.

Is it possible to pass something there which will force a compile time fail?

For example, given this templatized function:

template <typename T, typename R = enable_if_t<is_integral<T>::value, int>>
R foo(T bar) {return static_cast<R>(bar);}

This code will compile fine: foo(13) But this code will fail: foo(13.0).

The reason that foo(13.0) will fail at compile time is that enable_if_t is undefined. Is there a name for "undefined" that I can pass to the afore mentioned DefaultType?

If so I should be able to test this by calling foo<int, undefined>(13) and having it fail, if in fact undefined was the type I'm looking for.

EDIT:

Apparently more explanation is called for.

Dan's `static_case can be called like this:

template<class T>
typename static_switch<sizeof(T),
                       int, // default case
                       static_case<sizeof(char),char>,
                       static_case<sizeof(short),short>,
                       static_case<sizeof(long),long>,
                       static_case<sizeof(long long),long long>>::type foo(T bar){ return reinterpret_cast<decltype(foo(bar))&>(bar);}

I want to pass "undefined" or whatever to that second parameter to make it fail to compile only when that parameter is evaluated. (The parameter marked "default case".)

In my simple test passing any two parameters to foo will succeed (for example foo<int, int>(13);) I want a parameter that would mimic the effect of enable_if_t causing it to fail (like when we call foo<double>(13.0);) In the example I said call foo<in, undefined>(13). I just want to know what "undefined" is.

Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • You may use Raymond Chen's answer to have the default case (which is the version non specialized of the template). – Jarod42 Feb 25 '15 at 16:23
  • @Jarod42 What are you saying that I could pass here? `foo(13);` – Jonathan Mee Feb 25 '15 at 16:27
  • If you specify `R`, you no longer use SFINAE. I'm not sure what you want to obtain exactly though. – Jarod42 Feb 25 '15 at 16:31
  • @Jarod42 If you look at `DefaultType` that's what is "fallen through" to if none of the other cases matched. I want to achieve a fail there without adding Dan's last edit: http://stackoverflow.com/revisions/28699568/4 – Jonathan Mee Feb 25 '15 at 16:45
  • 1
    I've read the original question, then yours about three times, and I still can't figure out what you're asking. Do you want `13.0` to fail? Do you want `13.0` to work? Some code demonstrating what you want to work, what you want to fail, and how you want it to fail would be great. – Mark B Feb 25 '15 at 16:52
  • @MarkB I have attempted to clarify, [Drax](http://stackoverflow.com/users/1147772/drax) seems to have the right answer. Perhaps his comment would be helpful in understanding: http://stackoverflow.com/questions/28724017/pass-a-failing-template-argument?noredirect=1#comment45739879_28724605 – Jonathan Mee Feb 25 '15 at 18:26
  • The linked answer has been edited to manage your case by introducing `struct fail_on_default {};` – Jarod42 Feb 26 '15 at 08:49
  • @Jarod42 Right, that's what I was trying to avoid. By using being able to pass "undefined" as the default argument I am able to preserve the functionality that *can* be defaulted if that is desired later in my program. – Jonathan Mee Feb 27 '15 at 11:34
  • @JonathanMee: `fail_on_default` is just a *special* default type, you still may use valid default type if needed. – Jarod42 Feb 27 '15 at 12:20

1 Answers1

2

The simplest way to have the undefined type you are talking about is:

std::enable_if_t<false>

So you can call your foo template like this:

foo<int, std::enable_if_t<false>>(13)

And have it fail as you asked.

Drax
  • 12,682
  • 7
  • 45
  • 85
  • Well I'm glad you get it. This is probably the correct answer. Anything I should have written up there that would have made it clearer for you? – Jonathan Mee Feb 25 '15 at 18:16
  • @JonathanMee Yeah, the `undefined` type is actually not a type. It is a template expression that cannot be evaluated because you seek something that doesn't exist, if it was a dynamic language like javascript sure it would be `undefined` but in a statically typed compiled language like c++ it's wrong to even refer to it as an `undefined` type and it should rather be seen as an `non evaluable` template expression. – Drax Feb 25 '15 at 18:22