I have this piece of code right there:
template <int V>
struct Constant {
constexpr operator int() const noexcept { return V; }
};
template <class T, int N>
struct Array { };
auto function(auto s) -> Array<int, s + s> {
return {};
}
auto const a = function(Constant<3>{});
To my greatest sadness, only Clang seems to accept this code.
Which compiler is right, and why?
I believe clang is correct here. Opened #114124 for gcc.
Note that both gcc and MSVC accept this equivalent formulation:
auto function(auto s) {
return Array<int, s+s>{};
}
It's just that they don't allow the use of the parameter in the return type.
But in the same way that writing s+s
as a constant expression in the body of the function doesn't violate any rules of [expr.const]/5, no rules are violated in the trailing-return-type. We're just as much not reading anything (i.e. the usual reason such programs fail is because we're attempting an lvalue-to-rvalue conversion on a value not known to the constant evaluator), since the conversion function to int
is constexpr
and doesn't rely on any data.