成员函数的实现取决于模板参数
member function implementation depending on template parameter
我有以下问题:
template< typename T, size_t N, size_t... N_i >
class A
{
public:
// ...
// first implementation
template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M!=1, size_t >::type = 0 >
A<T, N_i...> operator[]( size_t i )
{
A< T, N_i... > res{ ... };
return res;
}
// second implementation
template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M==1, size_t >::type = 0 >
T operator[]( size_t i )
{
return ... ;
}
};
正如你在上面看到的,我尝试实现一个类A
,它期望作为模板参数的类型是T
(例如int
或float
)和sizeof...(N_i)+1
-许多size_t
。
根据传递的size_t
(即sizeof...(N_i)+1
)的数量,我将使用具有不同结果类型的成员函数operator[](size_t)
的不同实现:
-
sizeof...(N_i)+1 > 1
的一个实现,返回类型A < T, N_i... >
(在代码中称为"第一次实现") - 和一个用于返回类型为
T
的casesizeof...(N_i)+1 == 1
(在代码中称为"第二次实现")。
不幸的是,我不知道如何实现这一点——上面的解决方案不起作用。有人知道吗?
提前感谢。
A<T, N_i...>
对于空N_i
无效。作为解决方案,您可以使用间接:
template <typename, std::size_t ...>
struct PopFrontA
{
using type = void; // Dummy type for A<T, N>
};
template< typename T, std::size_t N, std::size_t... N_i > class A;
template <typename T, std::size_t N, std::size_t N2, std::size_t ... Ns>
struct PopFrontA<T, N, N2, Ns...>
{
using type = A<T, N2, Ns...>;
};
template <typename T, std::size_t ... Ns>
using PopFrontA_t = typename PopFrontA<T, Ns...>::type;
和
// first implementation
template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M!=1, size_t >::type = 0 >
PopFrontA_t<T, N, N_i...>
operator[]( size_t i )
{
A< T, N_i... > res{ /*...*/ };
return res;
}
演示如果修改
A< T, N_i... > res{ ... };
A< T, N_i... > res{ };
和
return ... ;
return T{} ;
还不够吗?
—EDIT—
不:正如Jarod42指出的(谢谢!),是不够的。
所以我提出了以下解决方案,基于类模板专门化和std::conditional
来避免使用SFINAE
#include <iostream>
#include <type_traits>
template< typename, size_t...>
class A;
template< typename T, size_t N, size_t... N_i >
class A<T, N, N_i...>
{
public:
template <typename Next = typename std::conditional<sizeof...(N_i),
A<T, N_i...>, T>::type>
Next operator[] (size_t i)
{ return Next{}; }
};
int main(int argc, char* argv[])
{
A<int, 2, 4> a;
std::cout << a[1][2] << std::endl;
return 0;
}
如果你不想对A
进行专门化,你可以添加A
的子结构体来完成这些繁琐的工作。
#include <iostream>
#include <type_traits>
template< typename T, size_t N, size_t... N_i >
class A
{
template <typename U, size_t ... O_i>
struct Next
{ using type = A<U, O_i...>; };
template <typename U>
struct Next<U>
{ using type = U; };
public:
using next_t = typename Next<T, N_i...>::type;
next_t operator[] (size_t i)
{ return next_t{}; }
};
int main(int argc, char* argv[])
{
A<int, 2, 4> a;
std::cout << a[1][2] << std::endl;
return 0;
}
相关文章:
- 将强制转换简化为取决于参数的类型
- cpp 模板专用化,错误说参数 1 的类型为 T,这取决于参数 T
- 模板函数,其中模板参数类型取决于函数参数
- GCC:指定的界限取决于源参数的长度
- 具有尾随返回类型的通用 lambda,具体取决于 C++11 中的可变参数
- 类模板中的std ::数组的大小,具体取决于模板参数
- LIBELAS是否取决于相机参数
- 具有取决于模板参数的方法的模板类
- 模板层次结构中的可选虚拟函数,具体取决于参数
- 约束模板参数取决于传递的函子
- 为什么固定尺寸错误发生取决于默认参数
- C++14 lambda 的默认参数类型推导,具体取决于前面的参数
- 委托构造函数和默认参数,具体取决于其他参数
- 取决于参数的数量,将其返回结构对象,并将其分配给常规结构的对象
- 具有模板参数取决于参数列表
- 返回类型取决于模板参数
- 是否可以定义一个 C++11 可变参数类模板,其可变参数基数取决于整数模板参数
- 返回取决于sizeof的变量类型..参数包
- 模板化结构的友元函数,其参数类型取决于结构的内部
- 变量模板函数,其中返回类型取决于模板参数列表