固定大小参数包的状态

时间:2014-07-23 14:14:24

标签: c++ standards c++14

我目前对固定大小参数包C ++语言功能提案(n4072)的进展感到好奇。此功能允许以下内容成为有效的C ++语法:

void Foo( int...[10] iList );

这将允许各种有用的模板元编程功能。阴谋的主要原因是因为我正在创建一个库类,它表示具有任意等级的数学Tensor对象。

这将允许我在索引类时执行以下操作:

template <typename T, std::size_t... Sizes>
class CTensor {
      // ...
public:
     NumType& operator()( std::size_t...[sizeof...(Sizes)] coords ) 
     {
          // Return reference to element at the position specified
          // by coords.
     }
};

并按以下方式调用它:

CTensor<int, 3, 4, 5> tensor;
/* tensor( 1, 2, 3, 4 ) = 5; // Results in a descriptive compile-time error */
tensor( 1, 2, 3 ) = 5; // Sets the element at (1, 2, 3) to 5.

据我所知,在标准C ++ 11中没有办法实现这一点,所以我对这个提议很感兴趣,但我找不到工作组接受或拒绝的任何信息;任何人都可以提供更多信息吗?

3 个答案:

答案 0 :(得分:5)

您要求的内容可以通过标准C ++实现。一旦概念进入语言,它就会更容易。

以下是标准C ++中的实现:

template<std::size_t N, class...Ts>
constexpr bool exactly_N_types() {
  return sizeof...(Ts) == N;
}
template<bool b,class T=void>
using enable_if_t = typename std::enable_if<b,T>::type;
template<class T0>
constexpr bool can_all_convert_to { return true; }

template<class T0, class T1, class...Ts>
constexpr bool can_all_convert_to() {
  return std::is_convertible< T1, T0 >::value && can_all_convert_to<T0, Ts...>();
}

template <typename T, std::size_t... Sizes>
struct CTensor {
  template<class... sizes>
  enable_if_t<
    exactly_N_types< sizeof...(Sizes), sizes...>()
    && can_all_convert_to< std::size_t, sizes...>()
    ,NumType&
  >
  operator()( sizes... coords ) 
  {
      // Return reference to element at the position specified
      // by coords.
  }
};

过于冗长。我可以用exactly_N_types<?,?>替换sizeof...(Sizes)==sizeof...(sizes),这会减少批量,但我决定以伪概念的方式进行。

一旦我们有了概念,指定...[N]意味着什么就会更少(因为上面的大部分内容都会被简化),而且指定它意味着什么也会变得更容易。两者都是推迟...[N]的理由,直到概念出现在语言之后。 (另一方面,很多情况也是如此,上一次我们可能会试图推迟概念的功能,这本来就是一个错误!)

使用概念精简版,它看起来像:

template <typename T, std::size_t... s>
struct CTensor {
  template<Sizes... sizes> requires exactly_N_types<sizeof...(s), Sizes...>
  NumType& operator()( sizes... coords ) 
  {
      // Return reference to element at the position specified
      // by coords.
  }
};

或某些。

答案 1 :(得分:4)

Maurice Bos向Rapperswil介绍了它在进化组中的初步草案,并进行了投票,强烈鼓励他继续努力。然后,他在Post-Rapperswil邮件中正式提交了N4072,这意味着它将于10月再次在Urbana展出。因为它是一个核心变化,如果它通过它将成为C ++ 17的一部分,或者C ++ 14之后的下一个C ++版本。

答案 2 :(得分:0)

您的具体情况可以通过根据Sizes而根据std::size_t在模式上进行包装扩展来解决。将执行以下操作:

template <class T, std::size_t>
using depend_v = T;

// ...

T& operator()( depend_v<std::size_t, Sizes>... coords ) { /* ... */ }

See it live on Wandbox