【问题标题】:variable template "SFINAE" not working变量模板“SFINAE”不起作用
【发布时间】:2016-04-05 08:19:27
【问题描述】:

我正在尝试使用“SFINAE”实现 cbor 格式的尺寸代码,因为没有更好的词。但它不起作用,例如,size_code<3> 的计算结果为 0x1b。怎么了?

template <::std::size_t N,
  typename = ::std::enable_if_t<N <= 0x17>
>
constexpr ::std::uint8_t const size_code = N;

template <::std::size_t N,
  typename = ::std::enable_if_t<(N > 0x17) &&
    (N <= ::std::numeric_limits<::std::uint8_t>::max())
  >
>
constexpr ::std::uint8_t const size_code = 0x18;

template <::std::size_t N,
  typename = ::std::enable_if_t<
    (N > ::std::numeric_limits<::std::uint8_t>::max()) &&
    (N <= ::std::numeric_limits<::std::uint16_t>::max())
  >
>
constexpr ::std::uint8_t const size_code = 0x19;

template <::std::size_t N,
  typename = ::std::enable_if_t<
    (N > ::std::numeric_limits<::std::uint16_t>::max()) &&
    (N <= ::std::numeric_limits<::std::uint32_t>::max())
  >
>
constexpr ::std::uint8_t const size_code = 0x1a;

template <::std::size_t N,
  typename = ::std::enable_if_t<
    (N > ::std::numeric_limits<::std::uint32_t>::max()) &&
    (N <= ::std::numeric_limits<::std::uint64_t>::max())
  >
>
constexpr ::std::uint8_t const size_code = 0x1b;

【问题讨论】:

  • 它不应该评估任何东西。此代码格式错误,无法多重重新定义size_code
  • 您最好为此编写一个constexpr 函数。
  • @T.C. gcc 很奇怪,但 clang 意识到了这一点。
  • 我知道 constexpr 函数和带有静态 constexpr 成员解决方法的结构,但如果可能的话,我真的很想避免这种情况
  • @TartanLlama 我已取消删除。您可以发布您的答案,我会接受。

标签: c++ c++14 cbor


【解决方案1】:

你不能像那样重新定义变量模板,所以你的代码不应该工作。

使用constexpr 函数会更简单,如下所示:

template <typename T> constexpr T t_max = std::numeric_limits<T>::max(); 

constexpr std::uint8_t size_code (std::size_t n) { 
    if (n <= 0x17) return n; 
    if (n <= t_max<std::uint8_t>) return 0x18; 
    if (n <= t_max<std::uint16_t>) return 0x19; 
    if (n <= t_max<std::uint32_t>) return 0x1a; 
    if (n <= t_max<std::uint64_t>) return 0x1b; 
}

【讨论】:

    【解决方案2】:

    我的 2 美分:

    template <::std::size_t N, typename = void>
    constexpr ::std::uint8_t const size_code{};
    
    template <::std::size_t N>
    constexpr ::std::uint8_t const size_code<N, ::std::enable_if_t<N <= 0x17> > = N;
    
    template <::std::size_t N>
    constexpr ::std::uint8_t const size_code<N,
      ::std::enable_if_t<(N > 0x17) &&
        (N <= ::std::numeric_limits<::std::uint8_t>::max())
      >
    > = 0x18;
    
    template <::std::size_t N>
    constexpr ::std::uint8_t const size_code<N,
      ::std::enable_if_t<
        (N > ::std::numeric_limits<::std::uint8_t>::max()) &&
        (N <= ::std::numeric_limits<::std::uint16_t>::max())
      >
    > = 0x19;
    
    template <::std::size_t N>
    constexpr ::std::uint8_t const size_code<N,
      ::std::enable_if_t<
        (N > ::std::numeric_limits<::std::uint16_t>::max()) &&
        (N <= ::std::numeric_limits<::std::uint32_t>::max())
      >
    > = 0x1a;
    
    template <::std::size_t N>
    constexpr ::std::uint8_t const size_code<N,
      ::std::enable_if_t<
        (N > ::std::numeric_limits<::std::uint32_t>::max()) &&
        (N <= ::std::numeric_limits<::std::uint64_t>::max())
      >
    > = 0x1b;
    

    【讨论】:

      猜你喜欢
      • 2018-09-26
      • 2019-06-24
      • 2012-10-15
      • 1970-01-01
      • 2021-09-23
      • 2018-07-21
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多