C ++-如何确定函数的返回值类型?

时间:2019-10-03 14:38:15

标签: c++ templates types

我正在尝试构建具有两个属性的对象的矢量,键始终是字符串,值始终是T类型

当我遍历向量时,我需要能够确定value属性的类型,以便可以切换到case语句来对其进行处理。

如何确定向量对象的value get函数的返回值的类型?

我的课在这里:

template <class T>
class IEFIAttribute
{
    String key;
    T value;
    public: 
            IEFIAttribute(String key, T value)
            {
                this->key = key;
                this->value = value;
            }
            String getKey();
            T getValue();
};

template <class T>
String IEFIAttribute<T>::getKey()
{
    return this->key;
}

template <class T>
T IEFIAttribute<T>::getValue()
{
    return this->value;
}

在我的main.cpp中,以下工作正常:

...
                IEFIAttribute <String> att("testkey","testvalue");

                Serial.println("XXX Key: "+att.getKey());
                Serial.println("XXX Value: "+att.getValue());
...

运行的结果是:

XXX Key: testkey
XXX Value: testvalue

我想做的是打开att.getValue()的类型,以便如果它是字符串,我做一件事,如果它是xyz对象,则根据我的xyz规则进行处理。对象。

任何帮助将不胜感激!

亲切的问候!

2 个答案:

答案 0 :(得分:3)

#include <iostream>
#include <string>
#include <type_traits>
#include <vector>

using String = std::string;

template<class T>
class IEFIAttribute {
public:
    using value_type = T;   // add this to be able to query it later

    IEFIAttribute(const String& Key, const T& Value) : 
        key(Key),           // prefer using the member initializer list
        value(Value) 
    {}

    // instead of copies, return const references
    String const& getKey() const {
        return key;
    };
    T const& getValue() const {
        return value;
    }

private:
    String key;
    T value;
};

您可以对某些类型进行特殊处理。

使用 constexpr if 的模板:

template<typename T>
T special_1(const std::vector<IEFIAttribute<T>>& v, size_t idx) {
    if constexpr(std::is_same_v<T, String>) {
        std::cout << "special_1() String handler\n";
    } else if constexpr(std::is_same_v<T, int>) {
        std::cout << "special_1() int handler\n";
    } else {
        std::cout << "special_1() generic handler\n";
    }
    return v[idx].getValue();
}

具有专长的模板:

template<typename T>
T special_2(const std::vector<IEFIAttribute<T>>& v, size_t idx) {
    std::cout << "special_2() generic handler\n";
    return v[idx].getValue();
}

template<>
String special_2(const std::vector<IEFIAttribute<String>>& v, size_t idx) {
    std::cout << "special_2() String handler\n";
    return v[idx].getValue();
}

template<>
int special_2(const std::vector<IEFIAttribute<int>>& v, size_t idx) {
    std::cout << "special_2() int handler\n";
    return v[idx].getValue();
}

或使用添加的value_type进行查询:

int main() {
    std::vector<IEFIAttribute<String>> v1{{"testkey", "testvalue"}};
    std::vector<IEFIAttribute<int>> v2{{"testkey", 10}};

    // decltype(v1)::value_type is the vectors value_type
    // and the second value_type is the one added to your class

    if(std::is_same_v<decltype(v1)::value_type::value_type, String>) {
        std::cout << "is String\n";
    } else {
        std::cout << "is not String\n";
    }

    if(std::is_same_v<decltype(v2)::value_type::value_type, int>) {
        std::cout << "is int\n";
    } else {
        std::cout << "is not int\n";
    }

    std::cout << special_1(v1, 0) << "\n";
    std::cout << special_1(v2, 0) << "\n";
    std::cout << special_2(v1, 0) << "\n";
    std::cout << special_2(v2, 0) << "\n";
}

答案 1 :(得分:1)

完成所需内容的一种方法是在类中使用365D,然后为条件语句使用typedef的功能。

例如:

<type_traits>

然后

template <class T>
class IEFIAttribute
{
  public:
    typedef T value_type;

  // everything as before...

};