- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
你好我使用模板在 C++ 中编写代码,并尝试实现一个 SFINAE,当运算符 +
时被触发。不支持。我写了下面的代码
#include <iostream>
#include <type_traits>
class B
{
};
template<typename T1,typename T2>
struct IsSameT :std::false_type
{
//static constexpr bool value = false;
};
template<typename T>
struct IsSameT<T,T> :std::true_type
{
//static constexpr bool value = true;
};
template<typename T1, typename T2>
struct HasPlusT
{
private:
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
template<typename U1, typename = decltype(T1_t() + T2_t())>
static char test(void *);
template<typename>
static long test(...);
public:
static constexpr bool value = IsSameT<decltype(test<T1,T2>(nullptr)),char>::value;
};
template<typename T1,typename T2, bool = HasPlusT<T1,T2>::value>
struct PlusResultT
{
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
using Type = decltype(T1_t() + T2_t());
};
template<typename T1,typename T2>
struct PlusResultT<T1,T2,false>
{
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
using Type = decltype(T1_t() + T2_t());
};
int main()
{
constexpr bool value = HasPlusT<B,B>::value;
return 0;
}
我希望 constexpr bool value = HasPlusT<B,B>::value
返回 false
但产生了一个错误执行中有什么问题?
Class B has not an operator + and I expect that the constexpr bool value = >HasPlusT::value returns true. However a compilation error is generated no match for 'operator+' (operand types are 'HasPlusT::T1_t {aka B}' and >'HasPlusT::T2_t {aka B}') Demo.cpp /Demo C/C++ >Problem
==============================================
支持类模板的新实现。为什么以下实现无法验证运算符 + 是否存在
#include <iostream>
#include <type_traits>
#include <array>
#include <vector>
#include <utility>
template<typename T1,typename T2>
struct IsSameT :std::false_type
{
//static constexpr bool value = false;
};
template<typename T>
struct IsSameT<T,T> :std::true_type
{
//static constexpr bool value = true;
};
template<typename T, typename U>
struct IsFuntamentalHelper : IsSameT<T,U>
{
//static constexpr bool value = IsSameT<T,U>::value;
};
template<typename T>
struct IsFundamentalT : std::false_type
{
//static constexpr boo value = std::false_type;
};
template<>
struct IsFundamentalT<int> : IsFuntamentalHelper<int,int>
{
};
template<>
struct IsFundamentalT<float> : IsFuntamentalHelper<float,float>
{
};
template<>
struct IsFundamentalT<double> : IsFuntamentalHelper<double,double>
{
};
template<>
struct IsFundamentalT<long>: IsFuntamentalHelper<long,long>
{
};
template<typename T>
using enable_if_t = typename std::enable_if<IsFundamentalT<T>::value, T>::type;
template<typename T>
class A
{
public:
template<typename = enable_if_t<T>>
operator T()
{
return t ;
}
A<T>():t()
{
}
template<typename = enable_if_t<T>>
A<T>(T a)
{
std::cout << "integer" << std::endl;
this->t = a;
}
A<T>(A<T> const & a)
{
this->t = a.t;
}
public:
A<T> add(A<T> & a)
{
t += a.t;
return *this;
}
friend A<T> operator + (A<T> & a1, A<T> & a2)
{
return a1.add(a2);
}
T t;
};
template<typename T1, typename T2>
struct HasPlusT
{
private:
template <typename T>
using Rr = typename std::remove_reference<T>::type;
template<typename U1, typename U2>
static auto test(void *)
-> decltype(std::declval<Rr<U1>>() + std::declval<Rr<U2>>() , '0');
template<typename...>
static long test(...);
public:
static constexpr bool value
= IsSameT<decltype(test<T1,T2>(nullptr)),char>::value;
};
template<typename T1,typename T2, bool = HasPlusT<T1,T2>::value>
struct PlusResultT
{
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
using Type = decltype(T1_t() + T2_t());
};
template<typename T1,typename T2>
struct PlusResultT<T1,T2,false>
{
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
using Type = decltype(T1_t() + T2_t());
};
int main()
{
constexpr bool value = HasPlusT<A<int>,A<int>>::value;
std::cout << value << std::endl;
return 0;
}
最佳答案
尝试
template <typename T1, typename T2>
struct HasPlusT
{
private:
template <typename T>
using Rr = typename std::remove_reference<T>::type;
template<typename U1, typename U2>
static auto test(void *)
-> decltype(std::declval<Rr<U1>>() + std::declval<Rr<U2>>() , '0');
template<typename...>
static long test(...);
public:
static constexpr bool value
= IsSameT<decltype(test<T1,T2>(nullptr)),char>::value;
};
我的意思是...您的代码有几个问题。
排名不分先后。
1 - 如果您调用 test<T1,T2>(nullptr)
,您显式传递了两个模板类型;所以如果你定义 test
第二个参数有第二种类型
template<typename U1, typename = decltype(T1_t() + T2_t())>
static char test(void *);
第二个从未使用过。
2 - SFINAE 使用函数的模板参数;不使用类的模板参数。所以如果你尝试做一些事情
template<typename U1, typename U2, typename = decltype(T1_t() + T2_t())>
static char test(void *);
SFINAE 不起作用,因为您没有使用 U1
和 U2
(方法的模板参数)但带有 T1_t()
和 T2_t()
, 所以 T1
和 T2
, 类的模板参数。
所以我建议使用 using
Rr
删除引用
template <typename T>
using Rr = typename std::remove_reference<T>::type;
并且,为了更简单,通过返回类型使用 SFINAE
template<typename U1, typename U2>
static auto test(void *)
-> decltype(std::declval<Rr<U1>>() + std::declval<Rr<U2>>() , '0');
-- 编辑 --
OP 无法使用 std::declval()
.
I use mingw and for an unknown reason cannot recognize declval
所以我提出了一个胜于无的简单替代品(没有 std::add_rvalue_reference<T>::type
,以防你不能使用它)
template <typename T>
T declVal();
和HasPlusT
成为
template <typename T1, typename T2>
struct HasPlusT
{
private:
template <typename T>
using Rr = typename std::remove_reference<T>::type;
template<typename U1, typename U2>
static auto test(void *)
-> decltype(declVal<Rr<U1>>() + declVal<Rr<U2>>() , '0');
template<typename...>
static long test(...);
public:
static constexpr bool value
= IsSameT<decltype(test<T1,T2>(nullptr)),char>::value;
};
-- 编辑 2 --
OP 说
what modifications are needed to support check for class templates? I try to do this for a class A but seems not to work. See in the initial post.
不是类模板的问题。
问题是你的 operator+()
对于 A
类
friend A<T> operator + (A<T> & a1, A<T> & a2)
{ return a1.add(a2); }
是不寻常的,因为它(正确地)是一个 friend
类的函数,但接收对 A<T>
的引用(左引用),而不是常量对象(通常是 const
引用;第一个值可以是未引用的值),修改第一个接收到的参数(危险)并通过拷贝返回。
所以 HasPlusT
类(class)失败,因为 std::declval()
返回与 operator+
不匹配的右值引用对象要求 l 值。
我强烈建议您修改operator+()
如下( a1
和 a2
const
)
friend A<T> operator+ (A<T> const & a1, A<T> const & a2)
{ A<T> ret{a1}; return ret.add(a2); }
或者,也许更好,如下所示( a1
没有 &
, a2
const
)
friend A<T> operator+ (A<T> a1, A<T> const & a2)
{ return a1.add(a2); }
你会看到 HasPlusT
再次工作。
关于c++ - 基于 SFINAE 的特征来确定是否支持运算符 +,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51994788/
设置 我希望能够定义一个特征,使得任何实现该特征的结构不仅必须实现函数,而且还必须为某些常量指定值。所以也许是这样的: trait MyTrait { const MY_CONST: u8;
在我的 Web 应用程序中,授权用户至少有 4 个“方面”:http session 相关数据、持久数据、facebook 数据、运行时业务数据。 我决定使用案例类组合而不是特征至少有两个原因: 性状
我正在尝试使用以下代码从类中获取完整数据成员的列表: import std.stdio; import std.traits; class D { static string[] integr
我正在尝试实现 From对于我的一种类型。它应该消耗任意长度的行(仅在运行时已知)并从行中获取数据。编译器提示 &[&str; 2]不是 &[&str] ,即它不能将固定大小的切片转换为任意长度的切片
有人可以请你这么好心,并指出一种提取拟合树中使用的列/特征的方法,使用如下代码: library(dplyr) library(caret) library(rpart) df % dplyr
假设我定义了一个 Group所有组操作的特征。是否可以创建一个包装器AGroup超过 Group无需手动派生所有操作? 基本上,我想要这个: #[derive (Copy, Debug, Clone,
最近浏览了Markus Stocker的博客他很好地解释了如何在使用 observation 时表示传感器观察结果。 SSN 的模块本体论。我完全理解他的解释,但我发现有一件事多余地代表了一个的两个特
我有以下情况/代码; trait Model { def myField: String } case class MyModel(myField: String) extends Model
我想让一个案例类扩展一个特征 以下是我的要求: 我需要为 child 使用案例类。这是一个硬性要求,因为 scopt ( https://github.com/scopt/scopt ) parent
最近浏览了Markus Stocker的博客他很好地解释了如何在使用 observation 时表示传感器观察结果。 SSN 的模块本体论。我完全理解他的解释,但我发现有一件事多余地代表了一个的两个特
我有以下情况/代码; trait Model { def myField: String } case class MyModel(myField: String) extends Model
不确定标题是否完全有意义,对此感到抱歉。我是机器学习新手,正在使用 Scikit 和决策树。 这就是我想做的;我想获取所有输入并包含一个独特的功能,即客户端 ID。现在,客户端 ID 是唯一的,无法以
我想读取具有 Eigen 的 MNIST 数据集,每个文件都由一个矩阵表示。我希望在运行时确定矩阵大小,因为训练集和测试集的大小不同。 Map> MNIST_dataset((uchar*)*_dat
在 MATLAB 中,我可以选择一个分散的子矩阵,例如: A = [1 ,2 ,3;4,5,6;7,8,9] A([1,3],[1,3]) = [1,3;7,9] 有没有用 Eigen 做到这一点的聪
我在执行 Into 时遇到问题Rust 中通用结构的特征。下面是我正在尝试做的简化版本: struct Wrapper { value: T } impl Into for Wrapper {
我有这段 matlab 代码,我想用 Eigen 编写: [V_K,D_K] = eig(K); d_k = diag(D_K); ind_k = find(d_k > 1e-8); d_k(ind_
我正在使用 Eigen C++ 矩阵库,我想获取对矩阵列的引用。文档说要使用 matrix_object.col(index),但这似乎返回了一个表示列的对象,而不是简单地引用原始矩阵对象中的列。我担
在乘以很多旋转矩阵之后,由于舍入问题(去正交化),最终结果可能不再是有效的旋转矩阵 重新正交化的一种方法是遵循以下步骤: 将旋转矩阵转换为轴角表示法 ( link ) 将轴角转换回旋转矩阵 ( lin
定义可由命名空间中的多个类使用的常量的最佳方法是什么?我试图避免太多的继承,所以扩展基类不是一个理想的解决方案,我正在努力寻找一个使用特征的好的解决方案。这在 PHP 5.4 中是可行的还是应该采用不
定义可由命名空间中的多个类使用的常量的最佳方法是什么?我试图避免太多的继承,所以扩展基类不是一个理想的解决方案,我正在努力寻找一个使用特征的好的解决方案。这在 PHP 5.4 中是可行的还是应该采用不
我是一名优秀的程序员,十分优秀!