【问题标题】:Cut-over interfaces from const char*, char* arguments to std::string从 const char*、char* 参数到 std::string 的转换接口
【发布时间】:2019-01-30 02:53:50
【问题描述】:

我正在处理遗留的 C++ 代码,需要积极重构。代码中的主要问题是,大量传递const char*char* 参数,如下所示。 const char* 变量将传递内部 char 数组(主要是用户输入)进行验证,并传递 'char*` 以正常从扩展验证器获取任何错误详细信息。这种类型的代码在代码库中无处不在。

virtual bool ValidateField(const char* pointerToDataBuffer, char* error)
{
    // extended codes by client teams.
}

我正在考虑将接口更改如下,

virtual bool ValidateField(const std::string copyOfBufferInside, std::string& error)
{
   // do stuff as before.
}

我的问题:

  1. 这是否存在严重的性能问题?由于 std::string 构造。通常内部缓冲区的长度约为 0-31,未来可能会增加。
  2. 还有其他针对这种情况的紧凑重构建议吗?

注意:编译器是 GCC 4.9.3。

已编辑: 内部缓冲区变量在 char[] 中,而不是 std::string。将来可能会转换为 std::string 。但这里不是这样。

【问题讨论】:

  • 可能希望const std::string & Buffer,作为第一个函数参数
  • ... 除非您打算更改或移动对象(神秘的 // do stuff 会指示),在这种情况下会丢失 const 和引用。
  • 查看std::string_view 的缓冲区参数,但对于错误参数,最好使用std:;string& error。
  • 标记的重复正在解决其他问题。这是关于将内部缓冲区 (char[]) 转换为 std::string。内部 char[] 已填充,在这种情况下不考虑性能。

标签: c++ string function refactoring stdstring


【解决方案1】:

考虑使用基于类型的错误处理和 boost::string_view 来处理各种类似字符串的输入:

http://coliru.stacked-crooked.com/a/22e9ec17b14992d1

#include <string>
#include <boost/variant.hpp>
#include <boost/utility/string_view.hpp>
#include <iostream>
#include <type_traits>

struct validation
{
    struct error
    {
        std::string message;
    };

    struct success
    {

    };

    using result = boost::variant<success, error>;

    template<class OnSuccess, class OnFailure>
    struct visitor_impl : boost::static_visitor<void>
    {
        template<class A1, class A2>
        visitor_impl(A1&& s, A2&& f)
        : on_success(s)
        , on_failure(f)
        {}

        void operator()(success const&) const
        {
            on_success();
        }

        void operator()(error const& f) const
        {
            on_failure(f.message);
        }

        OnSuccess on_success;
        OnFailure on_failure;
    };

    template<class OnSuccess, class OnFailure>
    static auto visitor(OnSuccess&& s, OnFailure&& f)
    {
        using success_f = typename std::decay<OnSuccess>::type;
        using failure_f = typename std::decay<OnFailure>::type;
        return visitor_impl<success_f, failure_f>
        {
            std::forward<OnSuccess>(s),
            std::forward<OnFailure>(f)
        };
    }

};

validation::result ValidateField(boost::string_view value)
{
    auto result = validation::result(validation::success {});
    if (value != "foo")
        result = validation::error { "not foo" };
    return result;
}



int main()
{
    std::string bar = "bar";
    boost::apply_visitor(validation::visitor(
                        []() { std::cout << "is foo\n"; },
                        [](std::string const& msg) { std::cout << msg << '\n'; }
                    ), ValidateField(bar));

    std::string foo = "foo";
    boost::apply_visitor(validation::visitor(
                        []() { std::cout << "is foo\n"; },
                        [](std::string const& msg) { std::cout << msg << '\n'; }
                    ), ValidateField(foo));

    const char* pfoo = "foo";
    boost::apply_visitor(validation::visitor(
                        []() { std::cout << "is foo\n"; },
                        [](std::string const& msg) { std::cout << msg << '\n'; }
                    ), ValidateField(pfoo));


}

预期输出:

not foo
is foo
is foo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-23
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    相关资源
    最近更新 更多