Не уверен, что понять, но ... если вы хотите позволить вашему operator=()
только тогда, когда входящий MyArray<T>
это с T
, что является std::complex<U>
, почему не вы просто написать
template <typename F>
MyArray & operator= (MyArray<std::complex<F>> const & rhs)
{ return *this }
--EDIT--
I want to assign U
to std::complex<U>
, so 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;
}
- EDIT 2 -
but there's a second template parameter that I removed in the original question, thinking that I'm simplifying the issue for readability. But it was wrong of me to do that, because partial specializations of functions are not allowed in C++. So my template is template , not template , which is very different
Я не думаю, что это частичная специализация необходимой
#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;
}
Если проблема заключается в определении operator()
outsi де тело класса, я предлагаю следующее, модифицированный пример
#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;
}
- EDIT 3 -
Is there a way to do the same with the copy constructor? [...] It's quite tricky and seems impossible because there's no return type.
Да, есть способ
#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;
}
Соблюдайте добавлены линии = default
; без первого (я не знаю, что другие три полезны или нет) код не компилируется, потому что (если я правильно понимаю) конструктор копии SFINAE отключает (удаляет) конструктор копии по умолчанию, поэтому удаляет другие конструкторы по умолчанию и деструктор по умолчанию.
Можете ли вы показать нам весь ваш код? Есть ли у вас другие перегрузки 'operator ='? – refi64
Эти швы слишком сложны. Не 'template MyArray MyArray :: operator = (const std :: complex & rhs)' делать то, что вы хотите? –
NathanOliver
@ kirbyfan64sos Весь код действительно, действительно огромный. Я рад добавить любые бит, которые вам нужны. Да, есть еще один 'operator =', но это стандартный 'operator =' ничем особенным. –