【问题标题】:How to make _t version of SFINAE struct exposing static member value?如何使 _t 版本的 SFINAE 结构暴露静态成员值?
【发布时间】:2020-07-31 18:12:42
【问题描述】:

我的代码可以根据 C++ 类型识别您需要使用的 GL 类型。我想制作它的_t 版本(如std::decay_tstd::enable_if_t)但公开int 常量值

template <typename T, typename = void> struct GLType {};

template <typename T>
struct GLType<T, std::enable_if_t<std::is_same_v<std::remove_pointer_t<std::decay_t<T>>, float>>> {
   const static constexpr int type = GL_FLOAT;
};

template <typename T>
struct GLType<T, std::enable_if_t<std::is_same_v<std::remove_pointer_t<std::decay_t<T>>, double>>> {
   const static constexpr int type = GL_DOUBLE;
};

我的第一次尝试是

template <typename T>
using GLType_t = GLType<T>::type;

但这不起作用。甚至可以以相同的方式返回值而不是类型吗?
最后,我想要类似的东西

int a = GLType_t<float>;
// instead of
int a = GLType<float>::type; // which works fine btw

【问题讨论】:

  • 根据 POSIX 标准,以 _t 结尾的名称是为实现而保留的,因此如果您的目标是 POSIX 系统(例如 Linux),则不应以 _t 结尾。
  • @jesperjuhl 感谢您提供的信息,但无论如何我将其更改为 _v

标签: c++ templates struct template-meta-programming sfinae


【解决方案1】:

您似乎正在寻找variable-templates,它允许您执行此操作:

template <typename T>
inline constexpr int GLType_t = GLType<T>::type;

然后你可以像这样使用它:

int a = GLType_t<float>;

另外,我强烈建议您将int 成员命名为value,而不是type。名称很重要,type 只是一个实际上不是类型的成员的错误名称。

【讨论】:

  • 谢谢,这就是我想要的。是的,在那种情况下valuetype 更有意义
  • 我可能会推荐 GLType -> GLTypeTagGLTypeTag::type -> GLTypeTag::valueGLType_t -> GLType_v,最后两个符合 C++ 约定。 (见&lt;type_traits&gt;。)
  • C++17 起,inline constexpr int GLType_t = ....
【解决方案2】:

@cigien's answer 提供了与variable template 一起使用的方法。

但是,我想提出一种使用 s if constexpr 的少打字方法。整个样板特征代码将简单地分解为一个模板函数:

#include <type_traits>

template <typename T>
constexpr auto GLTypeHelper() noexcept
{
   // assert is the T is not either float or double
   static_assert(std::is_same_v<T, float> || std::is_same_v<T, double>, " T should be float or double");
   
   if constexpr (std::is_same_v<T, float>) 
      return GL_FLOAT;
   else if constexpr (std::is_same_v<T, double>) 
      return GL_DOUBLE;
};

// variable template for GLType_v
template <typename T>
inline constexpr int GLType_v = GLTypeHelper<T>(); // calls the `GLTypeHelper()`

你会像这样使用它

constexpr int a = GLType_v<float>;
constexpr int b = GLType_v<double>;

当然,因为 GL_FLOATGL_DOUBLE 是值,而不是类型,请更改 ::type -> ::value_t -> _v

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 2019-05-25
    相关资源
    最近更新 更多