使用SFINAE根据类模板参数的类型更改类中调用的函数
using SFINAE to change function called in a class depending on type of class template parameter
我有一个模板化的类,它可以采用标量或索引类型,我想根据它的类型调用不同版本的函数:
template <typename Ta, typename ... T>
struct MyClass {
Ta tt; //can be either a scalar (double, complex<double>, int, etc),
//or an indexed type (MyClass, std::vector<double>, double[], etc)
//....
//I would like the following to be called when tt is a scalar type:
auto operator[]( size_t i ) { return tt; };
//I would like the following to be called when tt has [] overloaded:
auto operator[]( size_t i ) { return tt[i]; };
};
有办法做到这一点吗?返回值SFINAE无效(因为此函数上没有模板参数(,基于类的SFINAE似乎无效(因为可变模板使末尾的伪模板参数无效(。还有其他想法吗?
我相信Xeo误解了Andrew所说的"标量"的含义。Xeo遵循C/C++对标量的定义(根据C++11,3.9/9(,Andrew的意思是更接近线性代数意义(向量空间底层场的元素(。例如,虽然Andrew的std::complex<double>
是标量,但Xeo的情况并非如此,因为他使用std::is_scalar<std::complex<double>>
来检查,当然,他得到了false
。
我相信,Andrew想要的是operator[](size_t i)
回归:
-
如果
tt[i]
合法,则为tt[i]
;或 -
如果
tt[i]
是非法的,则为tt
。
我们可以轻而易举地淘汰掉上面的第一位候选人。通过实现一个检查调用tt[i]
是否合法的特性,当表达式合法时,我们还可以SFINAE去掉第二个候选者。创建这个特性不是很简单,它依赖于过载解决方案(实际上是经典的no f(...)
(。我将跳过特性的创建,而是直接在MyClass
中使用相同的想法。为了避免用伪参数(重载解析技巧所需(污染operator[]()
的签名,我将创建名为value()
的私有方法,该方法使用伪参数。那么operator[]()
将仅将呼叫委派给其中一个。
代码如下。
#include <type_traits> // for std::declval
template <typename Ta>
class MyClass {
// This overload is SFINAEd away when tt[i] is illegal
template <typename T = Ta, typename R = decltype(std::declval<T>()[0])>
R
value(size_t i, int) { return tt[i]; }
// This one is always present but is a worse match than the other
// one when resolving value(i, 0).
const Ta&
value(size_t, ...) { return tt; }
public:
Ta tt;
auto operator[]( size_t i ) -> decltype(this->value(0, 0)) {
return value(i, 0);
}
};
只需给operator[]
s一个伪模板参数。
template<class U = Ta, EnableIf<std::is_scalar<U>>...>
auto operator[]( size_t i ){ return tt; };
template<class U = Ta, DisableIf<std::is_scalar<U>>...>
auto operator[]( size_t i ) { return tt[i]; };
请参阅此处了解有关这种特殊风格的SFINAE的一些解释。
相关文章:
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- C++ 这里有一个返回 (24) 的布尔返回类型函数
- 使用SFINAE来检测void返回类型函数的存在
- 使用此类型函数有什么优势
- 为什么此函数通过类型函数指针调用后,呼叫明智地行为
- 如何使用无类型函数指针调用C++成员函数
- 模板返回类型函数如何在C++中工作
- 具有通用类型函数的动态库[C ]
- 如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )
- Bon appetit :从 int 返回类型函数在 main() 中打印字符串
- 对于需要其他模板参数的类型函数的部分模板专业化
- c++错误的参数类型-函数指针
- 延迟评估模板类型函数
- 在引用或指针返回类型函数上输入
- 具有指针数据类型的非类型函数模板参数
- STL中使用的C++自定义比较类型(函数谓词与较少结构)
- C++模板基类的非类型函数模板的 using 声明
- 字符串到类型函数,模板专用化使调用统一
- 自由类型函数可以接受 Unicode 文件名吗?