(C++) 错误:从‘char’到‘const char*’的无效转换[-fpermissive]

时间:2021-03-16 06:35:13

标签: c++ string googletest

我正在尝试编写一个函数,该函数将从给定的开始和结束索引返回一个子字符串。这是我写的代码,但是当我运行它时,它给了我错误。我使用 gtest 来运行它而不是 main()。

template <typename S>
S substring(S string_, int Istart, int Iend)
{
    S substr = string_[Istart];
    for(int i=(Istart+1); i<Iend; i++)
    {
        substr += string_[i];
    }
    return substr;    
}

这是我得到的错误:

In file included from test.cpp:2:0:
lab2.cpp: In instantiation of ‘S substring(S, int, int) [with S = const char*]’:
test.cpp:56:1:   required from here
lab2.cpp:91:23: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
     S substr = string_[Istart];
                ~~~~~~~^

我的测试代码是这样的:

TEST(subStr, T1){
string str="he";
EXPECT_EQ(str,substring("hello", 0, 2));
}
TEST(subStr, T2){
string str="urge";
EXPECT_EQ(str,substring("hamburger", 4, 8));
}

2 个答案:

答案 0 :(得分:4)

使用给定的调用上下文,这个:

EXPECT_EQ(str,substring("hello", 0, 2));

利用

的扩展
substring<const char*>

因此结果代码变为:

const char* substring(const char* string_, int Istart, int Iend)
{
    const char* substr = string_[Istart];
    for(int i=(Istart+1); i<Iend; i++)
    {
        substr += string_[i];
    }
    return substr;    
}

显然这行不通。 const char* substr = string_[Istart]; 正在从 const char * 初始化 char。在我看来,你有两种选择,但只有一种是远程现实的。由于 EXPECT_EQ 测试等效性,因此无论如何都无法使用指针路由。您需要至少在该测试的一侧有一个可比较的std::string 保证,而唯一的方法是保证同时仍然提供您富有表现力的论点是这样的:

template<class S>
std::string substring(S s, int Istart, int Iend)
{
    return std::string(s).substr(Istart, Iend - Istart);
}

这会将与 std::string 兼容的任何内容作为源参数。结果始终是 std::string,然后可以将其用于与各种事物进行比较,包括 char[N]const char *,当然还有 std::string

它仍然有一个很大的警告,必须订购 IstartIend。消除这种脆弱性正是 substr 的标准库 std::string 成员不采用 begin,end; 的原因。它需要一个开始,长度。尽管如此,这很容易成为做你想做的事情的最简单的方法。(尽管单行性质表明这样的事情非常有用)。

示例

我没有 GoogleTest,但一个简单的断言宏将演示针对与 std::string 的不同比较进行的测试:

#include <iostream>
#include <string>
#include <cassert>

template<class S>
std::string substring(S s, int Istart, int Iend)
{
    return std::string(s).substr(Istart, Iend - Istart);
}


int main()
{
    const char *kvalptr = "welcome";
    std::string kvalstr = kvalptr;

    auto res = substring("abdwelcomedef", 3, 10);

    // test that both lhs prospects test against our result
    assert(kvalptr == res);
    assert(kvalstr == res);

    // output res and one of the prospects.
    std::cout << res << '\n' << kvalptr << '\n';
}

输出

welcome
welcome

答案 1 :(得分:0)

假设预期类型为 string+= 类型存在 string 运算符。

一个简单的解决方法是替换

S substr = string_[Istart];

S substr;
substr += string_[Istart];

这不适用于 const char* 类型

以下适用于 stringconst char*

#include <exception>
#include <iostream>
#include <functional>
#include <string>
#include <type_traits>

template <typename S>
S substring(S string_, int Istart, int Iend)
{
    if constexpr (std::is_same_v<S, std::string>) {
        if(Istart < Iend){
            return string_.substr(Istart, Iend-Istart);
        }
    }
    else if constexpr (std::is_same_v<S, const char*>) 
    {
        if(Istart < Iend){
            std::string temp = std::string(string_);
            return (temp.substr(Istart, Iend-Istart)).c_str();
        }
    } 
    else throw;
}
相关问题