Can constexpr-if-else bodies return different types in constexpr auto function?

戏子无情 提交于 2019-12-05 15:34:05

Yes, what you are attempting is allowed. The two relevant excerpts I've found in N4606 are:

6.4.1/2 [stmt.if]

If the if statement is of the form if constexpr [...] If the value of the converted condition is false, the first substatement is a discarded statement, otherwise the second substatement, if present, is a discarded statement.

Indicating an untaken branch in a constexpr if is a discarded statment. Further, auto functions only consider non-discarded return statements for deducing the return type

7.1.7.4/2 [dcl.spec.auto] (emphasis mine)

[...] If the declared return type of the function contains a placeholder type, the return type of the function is deduced from non-discarded return statements, if any, in the body of the function (6.4.1).

Simplified, the following code works on both gcc and clang head.

namespace {

enum class shape_type { TRIANGLE, RECTANGLE, CIRCLE};

template<shape_type>
struct shape { };

using triangle = shape<shape_type::TRIANGLE>;
using rectangle = shape<shape_type::RECTANGLE>;
using circle = shape<shape_type::CIRCLE>;

template<shape_type ST>
constexpr auto make() {
  if constexpr (ST == shape_type::TRIANGLE) {
    return triangle{};
  } else if constexpr (ST == shape_type::RECTANGLE) {
    return rectangle{};
  } else if constexpr (ST == shape_type::CIRCLE) {
    return circle{};
  } 
}

}

int main() {
  auto t = make<shape_type::TRIANGLE>();
  auto r = make<shape_type::RECTANGLE>();
  auto c = make<shape_type::CIRCLE>();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!