Шаблон с автоматическим возвратом возврата - PullRequest
0 голосов
/ 17 декабря 2018

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

template<typename T>
struct Number{
    const T value;
    Number(T a) : value(a) {}

    template<typename U>
    auto operator*(Number<U> other){
        auto new_value = value*other.value;
        std::cout << typeid(new_value).name() << std::endl;
        return Number(new_value);
    }
};

Теперь, если я выполню эту операцию с помощью следующего кода, вызываемого в main.Возвращает номер типа первого, а не номер более высокого типа.

auto b =  Number<int>(6) * Number<double>(2.3); // this should be an int*double=double
std::cout << b.value << typeid(b.value).name() << std::endl;
auto c = Number<double>(2.3) * Number<int>(6);
std::cout << c.value << typeid(c.value).name() << std::endl;

Вывод выглядит следующим образом: d 13i d 13.8d

Из того, что я понимаю, неверныйконструктор вызывается, когда функция возвращает новый Number(new_value).Я не понимаю, как и почему это происходит, поскольку new_value имеет «правильный тип».

Ответы [ 3 ]

0 голосов
/ 17 декабря 2018

Внутри области шаблона имя шаблона будет заменять введенное имя класса, а не шаблон.Таким образом, не будет CTAD, , и это по замыслу

Использование return Number<decltype(new_value)>(new_value); - это простое решение.

0 голосов
/ 17 декабря 2018

Поскольку StoryTeller указывает, в определении шаблона класса имя класса относится к конкретному экземпляру класса (известному как injected-class-name ), а не кимя шаблона.

Но если вы хотите, чтобы вывод аргумента шаблона класса все еще применялся, вы можете просто указать имя:

return ::Number(new_value);

::Number относится к шаблону класса Numberне конкретный тип Number<T>.Но это может быть слишком волшебным для других людей, читающих ваш код, и простое использование Number<decltype(new_value)>(new_value) имеет много преимуществ.

0 голосов
/ 17 декабря 2018

Вы возвращаете первый тип, а не второй:

template<typename U>
auto operator*(Number<U> other){
    auto new_value = value*other.value;
    std::cout << typeid(new_value).name() << std::endl;
    return Number(new_value);
}

Даже если new_value является двойным, вы сохраняете его в Number<T>.

Попробуйте:

template<typename U>
auto operator*(Number<U> other){
    auto new_value = value*other.value;
    std::cout << typeid(new_value).name() << std::endl;
    return Number<decltype(new_value)>(new_value);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...