c ++强制隐式转换作为参数传递
c++ Force implicit conversion on pass as argument
我对 C++ 中的隐式转换有疑问。
我正在尝试为矢量算术创建一些表达式模板(我知道相同的库已经存在。我只是在学习 C++,所以我想尝试使用模板)。
我想创建 class 向量,它可以像这样计算:
simd::test::Vector<char, 5> a;
simd::test::Vector<short, 5> b;
auto ret = a + b + a + b;
,其中输出将是 Vector of shorts 因为 short 是比 char 更大的类型。
现在,我有 class 可以添加相同数据类型的向量。对于不同的类型,我必须调用显式转换:
//simd::test::Vector<short, 5>(a)
auto ret = simd::test::Vector<short, 5>(a) + b + simd::test::Vector<short, 5>(a) + b;
是否可以在传递给函数之前隐式转换 Vector "operator+()"?这是我的 Vector 代码:
#pragma once
#include <type_traits>
namespace simd {
namespace test {
template<typename R, std::size_t Dim,
typename std::enable_if<std::is_arithmetic<R>::value>::type* = nullptr
>
class Vector_expression {
public:
static constexpr std::size_t size = Dim;
virtual const R operator[] (std::size_t index) const = 0;
virtual ~Vector_expression() = default;
};
template<typename T, std::size_t Dim>
class Vector final : public Vector_expression<T, Dim> {
private:
T data[Dim];
public:
Vector() = default;
template<typename R>
Vector(const Vector_expression<R, Dim> &obj) {
for(std::size_t index = 0; index < Dim; ++index) {
data[index] = obj[index];
}
}
template<typename R>
Vector(Vector_expression<R, Dim> &&obj) {
for(std::size_t index = 0; index < Dim; ++index) {
data[index] = obj[index];
}
}
template<typename R>
Vector<T, Dim> & operator=(const Vector_expression<R, Dim> &obj) {
for(std::size_t index = 0; index < Dim; ++index) {
data[index] = obj[index];
}
return (*this);
}
template<typename R>
Vector<T, Dim> & operator=(Vector_expression<R, Dim> && obj) {
for(std::size_t index = 0; index < Dim; ++index) {
data[index] = obj[index];
}
return (*this);
}
virtual const T operator[] (std::size_t index) const override {
return data[index];
}
T & operator[] (std::size_t index) {
return data[index];
}
virtual ~Vector() = default;
};
template<typename E1, typename E2, typename R, std::size_t Dim>
class Vector_sum final : public Vector_expression<R, Dim> {
private:
const E1 & _lhs;
const E2 & _rhs;
public:
Vector_sum() = delete;
Vector_sum(const E1 & lhs, const E2 & rhs) :
_lhs(lhs),
_rhs(rhs)
{}
virtual const R operator[] (std::size_t index) const override {
return _lhs[index] + _rhs[index];
}
virtual ~Vector_sum() = default;
};
template<typename R, std::size_t Dim>
Vector_sum<Vector_expression<R, Dim>, Vector_expression<R, Dim>, R, Dim> operator+ (const Vector_expression<R, Dim> & lhs, const Vector_expression<R, Dim> & rhs) {
return {lhs, rhs};
}
}
}
可以使用模板和 std::common_type
来完成,像这样:
template<typename T1, typename T2, size_t S>
simd::test::Vector<typename std::common_type<T1, T2>::type, S>
operator+(simd::test::Vector<T1, S> const& v1,
simd::test::Vector<T2, S> const& v2)
{
// TODO: Implementation...
}
只需定义一个允许不同参数类型的 operator+
。一个问题是确定结果总和的元素类型。可能最好的选择是使用添加两个元素的任何结果。这种类型的一种写法是:
decltype(std::declval<const R1>() + std::declval<const R2>())
或者,如果您知道类型是内置算术类型,那将与
相同
std::common_type_t<R1, R2>
或者使用尾随 return 类型,我们可以利用函数参数来缩短 std::declval
表达式:
template<typename R1, typename R2, std::size_t Dim>
auto operator+ (const Vector_expression<R1, Dim> & lhs,
const Vector_expression<R2, Dim> & rhs)
-> Vector_sum<Vector_expression<R1, Dim>, Vector_expression<R2, Dim>,
decltype(lhs[0] + rhs[0]), Dim>
{
return {lhs, rhs};
}
我对 C++ 中的隐式转换有疑问。
我正在尝试为矢量算术创建一些表达式模板(我知道相同的库已经存在。我只是在学习 C++,所以我想尝试使用模板)。
我想创建 class 向量,它可以像这样计算:
simd::test::Vector<char, 5> a;
simd::test::Vector<short, 5> b;
auto ret = a + b + a + b;
,其中输出将是 Vector of shorts 因为 short 是比 char 更大的类型。
现在,我有 class 可以添加相同数据类型的向量。对于不同的类型,我必须调用显式转换:
//simd::test::Vector<short, 5>(a)
auto ret = simd::test::Vector<short, 5>(a) + b + simd::test::Vector<short, 5>(a) + b;
是否可以在传递给函数之前隐式转换 Vector "operator+()"?这是我的 Vector 代码:
#pragma once
#include <type_traits>
namespace simd {
namespace test {
template<typename R, std::size_t Dim,
typename std::enable_if<std::is_arithmetic<R>::value>::type* = nullptr
>
class Vector_expression {
public:
static constexpr std::size_t size = Dim;
virtual const R operator[] (std::size_t index) const = 0;
virtual ~Vector_expression() = default;
};
template<typename T, std::size_t Dim>
class Vector final : public Vector_expression<T, Dim> {
private:
T data[Dim];
public:
Vector() = default;
template<typename R>
Vector(const Vector_expression<R, Dim> &obj) {
for(std::size_t index = 0; index < Dim; ++index) {
data[index] = obj[index];
}
}
template<typename R>
Vector(Vector_expression<R, Dim> &&obj) {
for(std::size_t index = 0; index < Dim; ++index) {
data[index] = obj[index];
}
}
template<typename R>
Vector<T, Dim> & operator=(const Vector_expression<R, Dim> &obj) {
for(std::size_t index = 0; index < Dim; ++index) {
data[index] = obj[index];
}
return (*this);
}
template<typename R>
Vector<T, Dim> & operator=(Vector_expression<R, Dim> && obj) {
for(std::size_t index = 0; index < Dim; ++index) {
data[index] = obj[index];
}
return (*this);
}
virtual const T operator[] (std::size_t index) const override {
return data[index];
}
T & operator[] (std::size_t index) {
return data[index];
}
virtual ~Vector() = default;
};
template<typename E1, typename E2, typename R, std::size_t Dim>
class Vector_sum final : public Vector_expression<R, Dim> {
private:
const E1 & _lhs;
const E2 & _rhs;
public:
Vector_sum() = delete;
Vector_sum(const E1 & lhs, const E2 & rhs) :
_lhs(lhs),
_rhs(rhs)
{}
virtual const R operator[] (std::size_t index) const override {
return _lhs[index] + _rhs[index];
}
virtual ~Vector_sum() = default;
};
template<typename R, std::size_t Dim>
Vector_sum<Vector_expression<R, Dim>, Vector_expression<R, Dim>, R, Dim> operator+ (const Vector_expression<R, Dim> & lhs, const Vector_expression<R, Dim> & rhs) {
return {lhs, rhs};
}
}
}
可以使用模板和 std::common_type
来完成,像这样:
template<typename T1, typename T2, size_t S>
simd::test::Vector<typename std::common_type<T1, T2>::type, S>
operator+(simd::test::Vector<T1, S> const& v1,
simd::test::Vector<T2, S> const& v2)
{
// TODO: Implementation...
}
只需定义一个允许不同参数类型的 operator+
。一个问题是确定结果总和的元素类型。可能最好的选择是使用添加两个元素的任何结果。这种类型的一种写法是:
decltype(std::declval<const R1>() + std::declval<const R2>())
或者,如果您知道类型是内置算术类型,那将与
相同std::common_type_t<R1, R2>
或者使用尾随 return 类型,我们可以利用函数参数来缩短 std::declval
表达式:
template<typename R1, typename R2, std::size_t Dim>
auto operator+ (const Vector_expression<R1, Dim> & lhs,
const Vector_expression<R2, Dim> & rhs)
-> Vector_sum<Vector_expression<R1, Dim>, Vector_expression<R2, Dim>,
decltype(lhs[0] + rhs[0]), Dim>
{
return {lhs, rhs};
}