根据模板类型在std :: to_string()和.toString()之间切换

时间:2016-02-03 16:51:12

标签: c++ string templates c++11

我目前正在使用C ++编写自己的PriorityQueue数据结构,我已将其作为typename T的模板类。

我班级的toString()成员函数定义为:

/**
 * @brief Gives a std::string representation of this queue structure
 *
 * The priority queue is returned as a string in the following format:
 *
 * \code{.cpp}
 * Data Item        Priority
 * [Item]           [P1]
 * [Item]           [P2]
 * [Item]           [P3]
 * \endcode
 *
 * where P1 < P2 < P3.
 *
 * @return String representation of this priority queue
 */
std::string toString() const {

    std::string tempString = "";

    // initialise temporary node to front of priority queue
    PQNode<T>* tempNode = front;

    // append string with headers
    tempString += "Data Item \t\t Priority\n";

    // while tempNode is not null, continue appending queue items to string
    while (tempNode != nullptr) {

        tempString += std::to_string(tempNode->head) + "\t\t\t " + std::to_string(tempNode->priority) + "\n";

        // shift tempNode to tail of current tempNode (moving along queue)
        tempNode = tempNode->tail;

    }

    return tempString;

}

如果模板的类型是std::to_string()intdouble等原语,我如何对此进行编码,以便在此方法中使用.toString()(如果模板的类型是具有自己的toString成员函数的类,则调用调用传递的类的toString方法?

我认为有一种方法可以使用#ifndef条款,但我没有太多使用这些条款的经验。

3 个答案:

答案 0 :(得分:6)

首先,为什么会出现DECLARE @DateLeft DATE; DECLARE @Level INT = 0; WHILE @Level < (SELECT COUNT(*) FROM SampleTable) BEGIN SELECT @DateLeft = [Date] From SampleTable Group By Code; --do something with @DateLeft SET @Level = @Level + 1; END

其次,具有std::priority_queue成员函数通常是设计错误,因为它通过数据表示硬连接数据逻辑。您应该做的是为您的班级重载toString,以便您可以将实例传递给任何operator<<

第三,你所要求的是在编译时选择&#34;正确&#34;字符串转换函数取决于类型是否具有std::ostream成员函数,并使用toString作为后备。这可以在C ++ 11中很好地实现,带有一些模板和std::to_string魔法。这是一个例子:

auto

输出:

#include <string>
#include <iostream>

struct Example
{
    std::string toString() const { return "foo"; }
};

template <class T>
auto ToString(T const& t) -> decltype(t.toString())
{
    std::cout << "Using toString\n";
    return t.toString();
}

template <class T>
auto ToString(T const& t) -> decltype(std::to_string(t))
{
    std::cout << "Using std::to_string\n";
    return std::to_string(t);
}

int main()
{
    Example e;
    std::cout << ToString(e) << "\n";

    int i = 0;
    std::cout << ToString(i) << "\n";
}

另请参阅C++11 ways of finding if a type has member function or supports operator?(尤其是用户的答案&#34; zah&#34;)。

不过,我强烈建议改为实施Using toString foo Using std::to_string 0 方法。

答案 1 :(得分:1)

执行此操作的一种方法是使用函数重载。对所有具有<select class="form-control" id="entityType" onchange={{action 'onSelectEntityType' value="target.value"}} > <option value="">Select</option> {{#each model as |entityType|}} <option value="{{entityType.id}}">{{entityType.entityTypeName}}</option> {{/each}} </select> 功能的类型使用函数模板。对需要使用toString的类型使用其他重载。

std::to_string

然后使用

template <typename T
std::string toString(T const& obj)
{
   return obj.toString();
}

std::string toString(int obj)
{
   return std::to_string(obj);
}

std::string toString(double obj)
{
   return std::to_string(obj);
}
tempString += toString(tempNode->head) + ... ; 中的

答案 2 :(得分:1)

使用已使用std::swap

建立的下一个模式

对于所有用户类型,在定义用户类型本身的同一名称空间中定义非成员to_string函数。此功能可以呼叫成员toString

std::string to_string(const UserType& x) {
    return x.toString();
}

然后在你的函数中调用to_string,如下所示:

some_function() {
    ...
    using std::string;
    ...
    tempString += to_string(tempNode->head) ... // note: unqualified to_string!
}

此解决方案使用名为ADL的C ++特性(依赖于参数的查找)。您可以在此处详细了解:http://en.cppreference.com/w/cpp/language/adl