У меня есть функция, которая принимает «авто» и возвращает «авто». Эта функция принимает числовые типы (например, сложный, целочисленный или двойной). Однако, в зависимости от результата функции, мне нужно что-то вернуть явно. Например, если в функцию передается комплексное число, мне нужно вернуть «complex (0, 0)», если «действительная» часть числа меньше нуля. Код выглядит примерно так:

if(myNumber<0){ return 0.0;} else{ return myNumber; }

Теперь, конечно, мне нужно перегрузить оператор «меньше чем», но сложность состоит в том, как разрешить возвращение 0, когда myNumber не является двойным. Я перегрузил оператор "=", чтобы разрешить присвоение двойных чисел комплексным числам, но все равно получаю ошибки компиляции.

Есть ли какой-нибудь хороший способ добиться этого?

Редактировать:

Мой полный код выглядит следующим образом.

auto BSCall(const auto &S0, const auto &k, const auto &discount, const auto &sigma){ 
if(sigma<=0){
    return 0.0;
}
else{
    double s=sqrt(2.0);
    auto d1=log(S0/(discount*k))/(sigma)+sigma*.5;
    return S0*(.5+.5*erf(d1/s))-k*discount*(.5+.5*(erf((d1-sigma)/s)));  
}}

Изменить еще раз:

Оказывается, у меня не было в моем классе конструктора, который взял бы двойной. Мой код работает, когда у меня есть перегруженный оператор "=" И конструктор с одним двойником.

1
user9403 2 Янв 2016 в 20:06

2 ответа

Лучший ответ

Я думаю, что вы столкнулись с проблемами, потому что у вас есть два возврата, которые возвращают разные типы, и компилятор не может решить, какой тип использовать в качестве возвращаемого типа.

Вы можете обойти это, поместив свои вычисления во вспомогательную функцию:

auto BSCallHelper(
        const auto &S0,
        const auto &k,
        const auto &discount,
        const auto &sigma
        )
{
    double s=sqrt(2.0);
    auto d1=log(S0/(discount*k))/(sigma)+sigma*.5;
    return S0*(.5+.5*erf(d1/s))-k*discount*(.5+.5*(erf((d1-sigma)/s))); 
}

Затем вы можете использовать вспомогательную функцию, чтобы указать тип возвращаемого значения:

auto BSCall(
        const auto &S0,
        const auto &k,
        const auto &discount,
        const auto &sigma
        ) -> decltype(BSCallHelper(S0,k,discount,sigma))
{ 
    if(sigma<=0){
        return 0.0;
    }

    return BSCallHelper(S0,k,discount,sigma);
}

Вы также можете использовать оператор ?: для определения общего типа:

auto BSCall(
        const auto &S0,
        const auto &k,
        const auto &discount,
        const auto &sigma
        )
{
    return (sigma<=0) ? 0 : BSCallHelper(S0,k,discount,sigma);
}
2
Vaughn Cato 2 Янв 2016 в 18:22

Я вижу два пути:

Сначала попробуйте список инициализаторов:

if(myNumber<0){
    return {};   //  <= it means you return T()
}else{
    return myNumber;
}

Во-вторых, использовать std::result_of из заголовка type_traits.

if(myNumber<0){
    return std::result_of<YourFunctionReference>::type();
}else{
    return myNumber;
}

Конечно, ваша функция является шаблонной, поэтому я не совсем уверен, сработает ли второй способ. Отправьте дополнительный код из вашего проекта, чтобы я мог рассказать вам, как использовать std::result_of в вашем случае.

3
fnc12 2 Янв 2016 в 17:18