我可以模板化以避免重写课程吗?

时间:2018-01-15 08:27:41

标签: c++ c++11 templates generics

我有一个针对某些特殊情况重写的类,但我想知道是否可以使用C ++泛型编程来决定函数包含的内容:

#include <iostream>
#include <typeinfo>
#include <string>


void printString(const std::string& str) { std::cout << str.c_str() << '\n'; }

template <typename T_callable>
struct FuncResultToString
{
    FuncResultToString(T_callable func) : call(func) {}
    T_callable call;

    void turnFuncResultToString()
    {
        std::string str = "Type: ";
        str += typeid(decltype(call())).name();
        str += " / Value: ";

        // IF RETURN TYPE IS CHAR* OR STRING
        str += call();
        // ELSE WILL HAVE TO TURN TO STRING FIRST
        str += std::to_string(call());

        printString(str);
    }
};


double afunction() { return double(5.0); }

int main()
{
    FuncResultToString<decltype(&afunction)> foo1(afunction);
    foo1.turnFuncResultToString();

    auto lambda = []() { return int(7); };
    FuncResultToString<decltype(lambda)> foo2(lambda);
    foo2.turnFuncResultToString();
}

打印出来:

Type: double / Value: 5.000000
Type: int / Value: 7

对于许多类型来说这很好,但是在callable返回char指针或std :: string的情况下我不想调用std :: to_string(),我只想按原样使用该值。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:5)

你可以超载:

const char* my_to_string(const char* s) { return s; }
const std::string& my_to_string(const std::string& s) { return s; }

template <typename T> std::string my_to_string(const T& s) { return std::to_string(s); }

然后:

void turnFuncResultToString()
{
    std::string str = "Type: ";
    str += typeid(decltype(call())).name();
    str += " / Value: ";
    str += my_to_string(call());

    printString(str);
}

答案 1 :(得分:4)

天真的解决方案是

void turnFuncResultToString()
{
    std::cout << "Type: ";
    std::cout << typeid(decltype(call())).name();
    std::cout << " / Value: ";

    std::cout << call();
}

如果您需要字符串本身,则可以使用std::stringstream ss;代替std::cout,然后使用printString(ss.str());