我希望我的数组类将数据从double
数组复制到std::complex<double>
(或任何U到std :: complex)数组,并使用operator=
。为此,我使用了std::enable_if
。但是,它未能检测到它不应该被使用。
以下函数,如果类型T
复杂,我想调用它。所以我使用条件std::is_same<T, std::complex<typename T::value_type>
,因为std::complex
存储了它在::value_type
中使用的类型。这是函数的定义:
template <typename T, int S>
typename std::enable_if<std::is_same<T, std::complex<typename T::value_type> >::value, MyArray<T,S>& >::type
MyArray<T,S>::operator=(const typename std::enable_if<std::is_scalar<typename T::value_type>::value, MyArray<typename T::value_type>&, S >::type rhs)
但是,如果我尝试复制MyArray<double>
,则会出现以下错误。显然,它没有发现double
不是“
错误:'double'不是类,结构或联合类型 MyArray :: operator =(const typename std :: enable_if :: value,MyArray&amp;,S&gt; :: type rhs)
我在这里做错了什么?
更新
我想让我想做的事情变得清晰,因为(抱歉)有太多混乱。
我需要这个操作:
MyArray<double> d;
MyArray<std::complex<double>> cd;
cd = d;
答案 0 :(得分:3)
不确定但是......如果您希望仅在传入的operator=()
与MyArray<T>
T
合并std::complex<U>
时才启用 template <typename F>
MyArray & operator= (MyArray<std::complex<F>> const & rhs)
{ return *this }
,为什么不要&#39}你简单地写一下
U
<强> - 编辑 - 强>
我想将
std::complex<U>
分配给MyArray<std::complex<U>> = MyArray<U>
,所以#include <complex> #include <type_traits> template <typename T> struct MyArray { template <typename U> typename std::enable_if<std::is_same<T, std::complex<U>>::value, MyArray &>::type operator= (MyArray<U> const & rhs) { return *this; } }; int main() { MyArray<double> d; MyArray<std::complex<double>> cd; cd = d; }
。
所以你想要完全相反。
我想你可以做点什么
#include <complex>
#include <type_traits>
template <typename T, int S>
struct MyArray
{
template <typename U>
typename std::enable_if<std::is_same<T, std::complex<U>>::value,
MyArray &>::type
operator= (MyArray<U, S> const & rhs)
{ return *this; }
};
int main()
{
MyArray<double, 3> d;
MyArray<std::complex<double>, 3> cd;
cd = d;
}
- 编辑2 -
但是我在原始问题中删除了第二个模板参数,认为我简化了可读性问题。但是我这样做是错误的,因为在C ++中不允许对函数进行部分特化。所以我的模板是模板,而不是模板,这是非常不同的
我认为这不是必要的部分专业化
operator()
如果问题在于定义班级正文之外的#include <complex>
#include <type_traits>
template <typename T, int S>
struct MyArray
{
template <typename U>
typename std::enable_if<std::is_same<T, std::complex<U>>::value,
MyArray &>::type
operator= (MyArray<U, S> const & rhs);
};
template <typename T, int S>
template <typename U>
typename std::enable_if<std::is_same<T, std::complex<U>>::value,
MyArray<T, S> &>::type
MyArray<T, S>::operator= (MyArray<U, S> const & rhs)
{ return *this; }
int main()
{
MyArray<double, 3> d;
MyArray<std::complex<double>, 3> cd;
cd = d;
}
,我建议以下修改后的例子
#include <complex>
#include <type_traits>
template <typename T, int S>
struct MyArray
{
template <typename U>
typename std::enable_if<std::is_same<T, std::complex<U>>::value,
MyArray &>::type
operator= (MyArray<U, S> const & rhs)
{ return *this; }
template <typename U,
typename = typename std::enable_if<std::is_same<T,
std::complex<U>>::value>::type>
MyArray (MyArray<U, S> const & rhs)
{ }
MyArray() = default;
MyArray(MyArray const &) = default;
MyArray(MyArray &&) = default;
~MyArray() = default;
};
int main()
{
MyArray<double, 3> d; // need MyArray() = default
MyArray<double, 3> d2(d); // OK
MyArray<float, 3> f; // OK
MyArray<std::complex<double>, 3> cd(d); // OK
//MyArray<std::complex<double>, 3> cd2(f); // error!
cd = d;
}
- 编辑3 -
有没有办法对拷贝构造函数做同样的事情? [...]这很棘手,似乎不可能,因为没有返回类型。
是的,有办法
= default
观察boolean
个添加的行;没有第一个(我不知道其他三个是否有用)代码没有编译,因为(如果我理解正确)SFINAE复制构造函数禁用(删除)默认复制构造函数所以删除其他默认构造函数和默认析构函数。
答案 1 :(得分:1)
在尝试理解模板问题时,我发现有些帮助,请自行尝试替换:
template <double>
typename std::enable_if<std::is_same<double, std::complex<typename double::value_type> >::value, MyArray<double>& >::type
MyArray<double>::operator=(const typename std::enable_if<std::is_scalar<typename double::value_type>::value, MyArray<typename double::value_type>& >::type rhs)
现在很明显吗?如果double
是MyArray
类型T
,那么T
将在上面的SFINAE逻辑中使用。但double
没有::value_type
。
您可以尝试这样的事情:
template<typename T>
typename std::enable_if<std::is_scalar<T>, MyArray<T>&>::type
MyArray<T>::operator=(const std::complex<T>& rhs){...}
如果您不需要is_scalar
检查,请改用max66的答案。
<强>更新强>
奥基-dokey。因此,此 地址希望通过赋值运算符从MyArray<T>
转到MyArray<std::complex<T>>
,而不是相反。
template<typename T, typename U>
typename std::enable_if<std::is_same<T, std::complex<U>>::value && std::is_scalar<U>::value, MyArray<T>&>::type
MyArray<T>::operator=(const MyArray<U>& rhs){...}
这里的诀窍是int
和std::complex<int>
不是同一类型。您也可以将T::value_type
替换为U
来完成此操作。最后,您可以通过对MyArray<T>
类进行部分专业化来实现它,以便MyArray<std::complex<T>>
类,如果您发现自己需要更多类似于您所要求的内容,则可能值得考虑。