1

I thought that conditional type could be declared using decltype in template functions. But it seems not. Could anyone point out what's wrong with my test code?

#include <boost/type_index.hpp>
using boost::typeindex::type_id_with_cvr;

#define print_type(var) do { \
  std::cout << type_id_with_cvr<decltype(var)>().pretty_name() << std::endl; \
} while(0)

template <typename T1, typename T2>
auto max(T1 a, T2 b) -> decltype(a < b ? b : a) {
  decltype(a < b ? b : a) c = a < b ? b : a;
  print_type(c);
  return a < b ? b : a;
}

int main() {
  int i = 10;
  double d = 3.3;

  decltype(i < d? d : i) r = i < d? d : i;
  print_type(r); // -> double
  std::cout << r << std::endl; // 10
}

1 Answer 1

4

I suppose that your intention with

decltype( a < b ? a : b )

was to obtain the type of b when a < b and the type of a otherwise.

That is: I suppose that your intention was to obtain a type determined run time according to the runt time values of a and b.

This is impossible in C++ because the type of a variable must be decided compile time.

With that decltype() you obtain the type of the ternary operator

a < b ? a : b

that doesn't depend from the values of a and b but only from their types.

So, in the case

decltype(i < d? d : i)

where i is an int and d is a double, you obtain a double and the values of i and d are irrelevant.

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

6 Comments

For what ground c++(decltype) decide to use double rather than int?
@DanielLee - For it being the common type between double and int.
@DanielLee, double is the common type of int and double. Mainly because converting int to double commonly either preserves the value or approximates it reasonably. In fact, it's common for conversions from a 32-bit int to a double to be non-narrowing, as IEEE-754 doubles can store up to ±2⁵³ without loss of precision. On the flip side, converting from double to int misses out on many, many values. C++ simply requires the conditional expression to resolve to a compile-time-known type, so it chooses the one that doesn't miss out on tons of values from the other.
std::conditional exists.... Yes, it must be decided at compile-time, but there's template magic to let you do stuff.
@DanielLee - There's no magic. C++ is a standardized language. You may read how the common type is deduced yourself. And FYI, you can only tag one person in a comment. You tagged me first, so only I was notified.
|

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.