我上课:
template <typename val_t>
class tracer_t : public base_tracer_t<val_t> {
std::vector<std::string> m_trace;
public:
virtual void push_fact(val_t fact) override {
std::string str = "+ fact: " + to_string(fact);
m_trace.push_back(std::move(str));
}
virtual void push_rule(const std::string &id, val_t val, bool tg) override {
std::string str = "+ ";
if (tg) { str += "target: "; }
else { str += "rule: "; }
str += id + " -> " + to_string(val);
m_trace.push_back(std::move(str));
}
virtual void print() override {
std::cout << "Stack trace: " << std::endl;
for (auto it = m_trace.begin(); it != m_trace.end(); ++it) {
std::cout << (*it) << std::endl;
}
}
private:
std::string to_string(val_t val) {
if (std::is_same<val_t, std::string>::value) {
return (std::string)val;
}
return std::to_string(val);
}
};
问题在于,由于以下原因,如果val_t
是std::string
则无法编译:
tracer.hpp:49: error: no matching function for call to ‘to_string(std::__cxx11::basic_string<char>&)’
return std::to_string(val);
~~~~~~~~~~~~~~^~~~~
但是我不知道如何解决它。我尝试手动检查类型,但在编译时出错,所以没有帮助
答案 0 :(得分:6)
如果您不想为std::string
专修整个课程,可以使用std::enable_if
或if constexpr
(c ++ 17)
auto to_string(val_t val)
-> typename std::enable_if<std::is_same<val_t, std::string>::value, std::string>::type
{
return static_cast<std::string>(val);
}
auto to_string(val_t val)
-> typename std::enable_if<!std::is_same<val_t, std::string>::value, std::string>::type
{
return std::to_string(val);
}
或更现代的方法,用if constexpr
auto to_string(val_t val)
{
if constexpr (std::is_same<val_t, std::string>::value)
{
return static_cast<std::string>(val);
}
else
{
return std::to_string(val);
}
}
答案 1 :(得分:5)
您可以为to_string
std::string to_string(const std::string& s) { return s; }
您可以将代码放在类中,作为私有方法,或放在合适的命名空间中,以免在有人使用您的代码并希望自己编写自己的{{1 }}。
编辑:如下面的评论所述,您不能在to_string
命名空间中放置这样的重载,因为禁止使用std
的新声明,请参见Extending the namespace std。
编辑:如果您可能需要调用std::to_string
,则可能需要向代码中添加一个附加的std::to_string
模板函数,
to_string
(为此请不要忘记template <typename T>
typename std::enable_if<!std::is_convertible<T, std::string>::value, std::string>::type to_string(T r) const { return std::to_string(r); }
)。
这是因为,即使您通过#include <type_traits>
导入标准库std::to_string
,成员函数using namespace std
也将具有优先级。请参阅讨论:C++: Why member function has priority over global function。 Here,您可以看到一个最小的示例。