首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果是其他的话,能不能在自动功能中返回不同的类型?

如果是其他的话,能不能在自动功能中返回不同的类型?
EN

Stack Overflow用户
提问于 2016-12-21 22:38:07
回答 1查看 4.1K关注 0票数 10

我试图编写一个函数,该函数根据枚举的运行时值将值的枚举映射到一组类型。我意识到您不能根据枚举的运行时值返回不同的类型,因为编译器不知道要分配多少堆栈空间。不过,我正在尝试将其编写为一个constexpr函数,使用新的if-constexpr功能来实现这一功能。

我从clang那里得到一个错误,抱怨我使用的是非法指定的模板参数。有人知道如何实现这一点吗?

编辑:这里有一个更简单易懂的版本,更简洁地演示了我的问题:http://coliru.stacked-crooked.com/a/2b9fef340bd167a8

旧代码:

代码语言:javascript
复制
#include <cassert>
#include <tuple>
#include <type_traits>

namespace
{

enum class shape_type : std::size_t
{
  TRIANGLE = 0u,
  RECTANGLE,
  POLYGON,
  CUBE,
  INVALID_SHAPE_TYPE
};

template<std::size_t T>
struct shape {
};

using triangle = shape<static_cast<std::size_t>(shape_type::TRIANGLE)>;
using rectangle = shape<static_cast<std::size_t>(shape_type::RECTANGLE)>;
using polygon = shape<static_cast<std::size_t>(shape_type::POLYGON)>;
using cube = shape<static_cast<std::size_t>(shape_type::CUBE)>;

template<std::size_t A, std::size_t B>
static bool constexpr same() noexcept { return A == B; }

template<std::size_t ST>
static auto constexpr make_impl(draw_mode const dm)
{
  if constexpr (same<ST, shape_type::TRIANGLE>()) {
    return triangle{};
  } else if (same<ST, shape_type::RECTANGLE>()) {
    return rectangle{};
  } else if (same<ST, shape_type::POLYGON>()) {
    return polygon{};
  } else if (same<ST, shape_type::CUBE>()) {
    return cube{};
  } else {
    assert(0 == 5);
  }
}

static auto constexpr make(shape_type const st, draw_mode const dm)
{
  switch (st) {
      case shape_type::TRIANGLE:
        return make_impl<shape_type::TRIANGLE>(dm);
      case shape_type::RECTANGLE:
        return make_impl<shape_type::RECTANGLE>(dm);
      case shape_type::POLYGON:
        return make_impl<shape_type::POLYGON>(dm);
      case shape_type::CUBE:
        return make_impl<shape_type::CUBE>(dm);
      case shape_type::INVALID_SHAPE_TYPE:
        assert(0 == 17);
  }
}

} // ns anon

////////////////////////////////////////////////////////////////////////////////////////////////////
// demo
int main()
{
}

错误:

代码语言:javascript
复制
/home/benjamin/github/BoomHS/main.cxx:42:6: warning: constexpr if is a
C++1z extension [-Wc++1z-extensions]

if constexpr (same<ST, shape_type::TRIANGLE>()) {
        ^ /home/benjamin/github/BoomHS/main.cxx:59:16: error: no matching function for call to 'make_impl'
        return make_impl<shape_type::TRIANGLE>(dm);
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/benjamin/github/BoomHS/main.cxx:40:23: note: candidate template
ignored: invalid explicitly-specified argument for template parameter
'ST' static auto constexpr make_impl(draw_mode const dm)
                      ^ /home/benjamin/github/BoomHS/main.cxx:61:16: error: no matching function for call to 'make_impl'
        return make_impl<shape_type::RECTANGLE>(dm);
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/benjamin/github/BoomHS/main.cxx:40:23: note: candidate template
ignored: invalid explicitly-specified argument for template parameter
'ST' static auto constexpr make_impl(draw_mode const dm)
                      ^ /home/benjamin/github/BoomHS/main.cxx:63:16: error: no matching function for call to 'make_impl'
        return make_impl<shape_type::POLYGON>(dm);
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/benjamin/github/BoomHS/main.cxx:40:23: note: candidate template
ignored: invalid explicitly-specified argument for template parameter
'ST' static auto constexpr make_impl(draw_mode const dm)
                      ^ /home/benjamin/github/BoomHS/main.cxx:65:16: error: no matching function for call to 'make_impl'
        return make_impl<shape_type::CUBE>(dm);
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/benjamin/github/BoomHS/main.cxx:40:23: note: candidate template
ignored: invalid explicitly-specified argument for template parameter
'ST' static auto constexpr make_impl(draw_mode const dm)
EN

回答 1

Stack Overflow用户

发布于 2016-12-21 22:53:53

是的,你正在尝试的东西是允许的。我在N4606中找到的两个相关摘录如下:

6.4.1/2 stmt.if

如果If语句的形式是if警员..。如果转换条件的值为false,则第一次子语句为丢弃语句,否则第二次子语句(如果存在)是被丢弃的语句。

表示一个未被占用的分支,如果是一个丢弃的状态的话。此外,auto函数仅考虑用于推断返回类型的未丢弃的返回语句。

7.1.7.4/2 dcl.spec.auto

..。如果函数的声明返回类型包含占位符类型,则函数的返回类型是从函数正文(6.4.1)中的非丢弃返回语句(如果有的话)推导出来的。

简化后的代码可以同时工作在gcc嘎吱声头上。

代码语言:javascript
复制
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>();
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41273101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档