我目前对固定大小参数包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中没有办法实现这一点,所以我对这个提议很感兴趣,但我找不到工作组接受或拒绝的任何信息;任何人都可以提供更多信息吗?
答案 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 ) { /* ... */ }