1

std::stringaを 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 に答える