c++ 无法在返回值中将“std::__cxx11::basic_string”转换< char>为“int”;

mrwjdhj3  于 2023-05-08  发布在  其他
关注(0)|答案(1)|浏览(478)

keyGenerator应该检查哪个数据类型作为参数给出,并将其转换为整数。它适用于float和double,但当试图将字符串转换为整数时,它不起作用。你知道为什么会这样吗?

#include <iostream>
#include <typeinfo>
#include <string>
#include <cmath>
using namespace std;

template<typename T>
class KeyValueKnot
{
public:
    T value;
    int key;
    KeyValueKnot *next;

    KeyValueKnot(T value)
    {
        this->value = value;
        this->key = keyGenerator(value);
        this->next = NULL;
    }
    int keyGenerator(T value)
    {
        if (typeid(value) == typeid(std::string))
        {
            return (int) generateNumberFromString(value);
        }
        else if (typeid(value) == typeid(double))
        {
            return static_cast<int>(value);
        }
        else if (typeid(value) == typeid(int))
        {
            return value;
        }
        else
        {
            std::cout << "Unknown type" << std::endl;
        }
        
    }
    
    int generateNumberFromString(string str)
    {
        int result = 0;
        for (char c : str)
        {
            result += static_cast<int>(c);
        }
        return result;
    }
    
};
aurhwmvo

aurhwmvo1#

你的if是在 * 运行时 * 计算的,所以所有的分支都需要在 * 编译时 * 有效。
然而,当T不是std::string时,表达式generateNumberFromString(value)对于任何不能 * 隐式 * 转换为std::stringT类型都无效。
而且,当Tstd::string时,表达式static_cast<int>(value)return value;无效,因为std::string不能转换为int
为了解决这个问题,你需要使用if constexpr(或者SFINAE或模板专门化,如果你使用的是C++17之前的编译器),所以if分支在 * 编译时 * 计算,允许编译器删除未使用的分支,例如:

#include <type_traits>

template<typename T>
inline constexpr bool always_false_v = false;

int keyGenerator(T value)
    {
        if constexpr (std::is_same_v<T, std::string>)
        {
            return (int) generateNumberFromString(value);
        }
        else if constexpr (std::is_same_v<T, double>)
        {
            return static_cast<int>(value);
        }
        //else if constexpr (std::is_same_v<T, int>)
        else if constexpr (std::is_convertible_v<T, int>) 
        {
            return value;
        }
        else
        {
            static_assert(always_false_v<T>, "Unknown type");
        }
    }

有关static_assert中需要always_false_v的原因,请参阅How can I create a type-dependent expression that is always false?(提示:如果没有它,代码将 * 总是 * 失败,并出现assert错误!).

相关问题