MSVC fails to deduce the result type of a ternary expression.
See http://en.cppreference.com/w/cpp/language/operator_other "Conditional Operator" for reference. https://godbolt.org/g/iqvLSB for live repro
Repro code is :
#include <utility>
#include <type_traits>
template <typename B, typename T, typename U>
decltype(auto) ternary(B&& expr, T&& lhs, U&& rhs) {
return std::forward<B>(expr) ? std::forward<T>(lhs) : std::forward<U>(rhs);
}
int main() {
const int c = 1;
volatile int v = 2;
int l = 3;
const volatile int cv = 4;
//////////////
// Identity //
//////////////
// const lvalue
static_assert(std::is_same_v<decltype(ternary(true, c, c)), const int&>);
static_assert(std::is_same_v<decltype(ternary(false, c, c)), const int&>);
// volatile lvalue
static_assert(std::is_same_v<decltype(ternary(true, v, v)), volatile int&>);
static_assert(std::is_same_v<decltype(ternary(false, v, v)), volatile int&>);
// lvalue
static_assert(std::is_same_v<decltype(ternary(true, l, l)), int&>);
static_assert(std::is_same_v<decltype(ternary(false, l, l)), int&>);
// rvalue
#ifndef _MSC_VER
static_assert(std::is_same_v<decltype(ternary(true, 1, 1)), int&&>);
static_assert(std::is_same_v<decltype(ternary(false, 1, 1)), int&&>);
#else
static_assert(std::is_same_v<decltype(ternary(true, 1, 1)), int>);
static_assert(std::is_same_v<decltype(ternary(false, 1, 1)), int>);
#endif
// const volatile lvalue
static_assert(std::is_same_v<decltype(ternary(true, cv, cv)), const volatile int&>);
static_assert(std::is_same_v<decltype(ternary(false, cv, cv)), const volatile int&>);
///////////
// Tests //
///////////
// const lvalue vs volatile lvalue
#ifndef _MSC_VER
static_assert(std::is_same_v<decltype(ternary(true, c, v)), int>);
static_assert(std::is_same_v<decltype(ternary(false, c, v)), int>);
#else
static_assert(std::is_same_v<decltype(ternary(true, c, v)), int&>);
static_assert(std::is_same_v<decltype(ternary(false, c, v)), int&>);
#endif
// const lvalue vs lvalue
#ifndef _MSC_VER
static_assert(std::is_same_v<decltype(ternary(true, c, l)), const int&>);
static_assert(std::is_same_v<decltype(ternary(false, c, l)), const int&>);
#else
static_assert(std::is_same_v<decltype(ternary(true, c, l)), int&>);
static_assert(std::is_same_v<decltype(ternary(false, c, l)), int&>);
#endif
// const lvalue vs rvalue
static_assert(std::is_same_v<decltype(ternary(true, c, 1)), int>);
static_assert(std::is_same_v<decltype(ternary(false, c, 1)), int>);
// const lvalue vs const volatile lvalue
#ifndef _MSC_VER
static_assert(std::is_same_v<decltype(ternary(true, c, cv)), const volatile int&>);
static_assert(std::is_same_v<decltype(ternary(false, c, cv)), const volatile int&>);
#else
static_assert(std::is_same_v<decltype(ternary(true, c, cv)), int&>);
static_assert(std::is_same_v<decltype(ternary(false, c, cv)), int&>);
#endif
// ---
// volatile lvalue vs lvalue
#ifndef _MSC_VER
static_assert(std::is_same_v<decltype(ternary(true, v, l)), volatile int&>);
static_assert(std::is_same_v<decltype(ternary(false, v, l)), volatile int&>);
#else
static_assert(std::is_same_v<decltype(ternary(true, v, l)), int&>);
static_assert(std::is_same_v<decltype(ternary(false, v, l)), int&>);
#endif
// volatile lvalue vs rvalue
static_assert(std::is_same_v<decltype(ternary(true, v, 1)), int>);
static_assert(std::is_same_v<decltype(ternary(false, v, 1)), int>);
// volatile lvalue vs const volatile lvalue
#ifndef _MSC_VER
static_assert(std::is_same_v<decltype(ternary(true, v, cv)), const volatile int&>);
static_assert(std::is_same_v<decltype(ternary(false, v, cv)), const volatile int&>);
#else
static_assert(std::is_same_v<decltype(ternary(true, v, cv)), int&>);
static_assert(std::is_same_v<decltype(ternary(false, v, cv)), int&>);
#endif
// ---
// lvalue vs rvalue
static_assert(std::is_same_v<decltype(ternary(true, l, 1)), int>);
static_assert(std::is_same_v<decltype(ternary(false, l, 1)), int>);
// lvalue vs rvalue
#ifndef _MSC_VER
static_assert(std::is_same_v<decltype(ternary(true, l, cv)), const volatile int&>);
static_assert(std::is_same_v<decltype(ternary(false, l, cv)), const volatile int&>);
#else
static_assert(std::is_same_v<decltype(ternary(true, l, cv)), int&>);
static_assert(std::is_same_v<decltype(ternary(false, l, cv)), int&>);
#endif
// ---
// rvalue vs const volatile lvalue
static_assert(std::is_same_v<decltype(ternary(true, 1, cv)), int>);
static_assert(std::is_same_v<decltype(ternary(false, 1, cv)), int>);
}
Issue is being experienced in pylene/tests/core/image/image_ops.cpp:183 in test Image2d_WhereOperator : const qualifier is dropped by msvc.