1

不能将 a 分配std::string给 a char[n](它会产生错误error: incompatible types in assignment),但通常可以使用 a 解决此问题strcopy(例如first answer)。

我正在寻找类似的技巧来初始化 POD 中的 char[n] 。这是我想做的事情:

#include <string>
typedef struct{
    char str[16];
} Pod;

int main() {       
    std::string s("does not compile");
    Pod pod = {s};
}

此代码产生以下错误:error: cannot convert ‘std::string {aka std::basic_string<char>}’ to ‘char’ in initialization.

谢谢


编辑:我非常喜欢允许我对 Pod 和字段进行 const 的解决方案。另外,我想保留初始化程序,现实世界中的字段不止一个。


编辑2:只是提醒一下以下代码有效,因此可以做一些小而漂亮的事情:Pod pod = {"this works"}

4

2 回答 2

6

首先初始化一个Pod对象,然后将字符串数据复制到该成员。

Pod pod;
assert(s.size()+1 <= sizeof(pod.str));
std::memcpy(&pod.str[0], s.data(), s.size()+1);

如果你想要一个Pod const,你可以利用 RVO:

Pod make_pod(std::string const& s) {
    Pod pod;
    assert(s.size()+1 <= sizeof(pod.str));
    std::memcpy(&pod.str[0], s.c_str(), s.size()+1);
    return pod;
}

Pod const pod = make_pod(s);

但是,如果你有很多,手动初始化所​​有成员有点烦人。如果数组在最后,它就没有那么糟糕了。

于 2013-06-14T12:56:42.703 回答
2

使用一些 C++11:

// sequence creation code from: http://stackoverflow.com/a/13315884/420683
template<unsigned... Is>
struct seq{};

template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};

    template<unsigned... Is>
    struct gen_seq<0, Is...> : seq<Is...>{};


#include <string>
struct Pod{
    char str[16];
};

template < unsigned... Is >
Pod create_pod(std::string const& p, seq<Is...>)
{
    if(p.size() >= sizeof...(Is))
    {
        return {p[Is]..., '\0'}; // if it has to be 0-terminated
    }else
    {
        // quick fix, there are better ways though
        char t[sizeof...(Is) +1];
        std::copy(p.begin(), p.end(), std::begin(t));
        t[p.size()] = '\0';

        return {t[Is]...};
    }
}
Pod create_pod(std::string const& p)
{
    return create_pod( p, gen_seq<sizeof(Pod::str) -1 >{} );
}

int main() {       
    std::string s("does not compile");
    Pod pod = create_pod(s);
}

或者,使用递归(未经测试!):

template < unsigned... Is >
Pod create_pod(std::string const& p, seq<Is...>, seq<>)
{
    return {p[Is...], '\0'};
}

template < unsigned... Is, unsigned... Is0 >
Pod create_pod(std::string const& p, seq<Is...>, seq<Is0...>)
{
    if(sizeof(Pod::str) > sizeof...(Is) && p.size() > sizeof...(Is))
    {
        create_pod(p, gen_seq<sizeof...(Is)+1>{}, gen_seq<sizeof...(Is0)-1>{});
    }else
    {
        return {p[Is]..., 0*Is0..., '\0'};
    }
}

Pod create_pod(std::string const& p)
{
    return create_pod( p, gen_seq<0>{},
                       gen_seq<sizeof(Pod::str) -1 >{} );
}
于 2013-06-14T13:16:57.540 回答