Unexpected nvc++ warning with conversion operator templates

Hi,

With the attached C++ code, nvc++ 21.7 produces two warnings indicating the conversion operators will not be used. The code nevertheless runs, and they are used, as I would expect.

Cheers,
Paul
conversion.cpp (336 Bytes)

Hi Paul,

I needed to ask engineering about this one. Basically the warning is correct, albeit not very clear. It’s essentially saying that a conversion operator to the class itself is useless and will never be called.

In your example, the warning about “operator Foo<float>” happens only when “Foo<float>” is instantiated, not when “Foo<double>” is instantiated. Similarly for the warning about “operator Foo<int>”.

With a class template, the warning is still correct, but it is not as useful. The code isn’t trying to use “operator Foo<float>” to convert a “Foo<float>” to a “Foo<float>”. It is using the conversion operator to convert a “Foo<double>” to a “Foo<float>”, which is a legitimate thing to do.

If want to avoid the warning, since it is not particularly useful in this case, you can change they conversion operator to:

template <typename U = float> operator typename std::enable_if<!std::is_same<T, U>::value, Foo<U>>::type () const { return {}; }

But that’s a really ugly workaround.

Alternately use the “–diag_suppress” command-line option to just turn off the warning entirely.

As far as I can tell, g++ doesn’t issue this warning, but Intel does as well. But Intel uses the same EDG C++ front-end as us so this would make sense as the warning is coming from EDG.

-Mat

Thanks Mat, that really helped (especially the SFINAE code). In the end, I decided to suppress the warning using diag_suppress as you suggest, and applied it locally using a pragma, as in:

template <typename T>
struct Foo {
#pragma diag_suppress = conversion_function_not_usable
           operator Foo<float>() { std::cout << "Hi 1!\n"; return {}; }
  explicit operator Foo<int>()   { std::cout << "Hi 2!\n"; return {}; }
#pragma diag_default = conversion_function_not_usable
};

Cheers,
Paul