48466


c++はstring型を使ってやれば文字列を簡単に扱えると思うのですが、あえて`const
char*`型を使って文字列を扱おうと思うのですが、どうすれば`const char*`型の文字列を連結できるのですか？

例: "abc" "abcc" の二つの`const char*`型を連結して "abcabcc" と一つの`const
char*`型に入れたいです。調べてこの関数を使って入れたのですが、`rsize_t`型と`size_t`型の違いについても教えていただけますでしょうか？

[code]

    template<typename type> type f(type a,type b) {
        cout << "テンプレート関数\n";
        return a + b;
    }
    
    template<> const char* f<const char*>(const char* x, const char* y) {
        //cout << "明示的特殊化\n";
        char* xx = const_cast<char*>(x);
        rsize_t t = sizeof(xx);
        strcat_s(xx, strlen(xx), y);  //ここの関数で書き込みアクセスエラーが出ます。
        cout << xx;
        return  "a";
    }
    
    int main() {
        cout << f<const char*>("abc", "abcc");
        _getch();
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2018-09-16T14:49:49.760
48465
2018-09-18T01:06:45.583
2018-09-18T01:06:45.583
3060
question
c++
c++でconst char*型の文字列をテンプレート関数で連結したい


2つ誤りがあると考えます。

  1. 呼び出し元で渡している引数`"abc"`には結合後の文字列`"abcabcc"`"を格納するだけのサイズがない可能性があります。
  2. 呼び出し元では文字列定数を渡していますが、多くのコンパイラでは文字列定数を変更不能なメモリ領域に配置することが多いため、結合する際にアクセスエラーになる可能性があります。

動作させるには、次の2つのどちらかの修正を行うとよいと思います。

＃一長一短です。後者はメモリリークの可能性があるので、前者の方が比較的よいと思います。

  1. 呼び出し元で`"abc"`を結合後の文字数以上の配列に格納してテンプレート関数を呼び出す

追記  
コメントの指摘通り、案1のコード例で配列`z`のサイズ計算が間違ってました。例を訂正します。  
(`sizeof(xx)`だと`sizeof(const char*)`なので、期待通りになりません)

[code]

        int main() {
            const char xx[] = "abc";
            const char yy[] = "abcc";
            // 必要最小限のサイズより大きくなるのは割り切りです。
            char z[sizeof(xx) + sizeof(yy)] = "abc";
            cout << f<const char*>(&z[0], &yy[0]);
            // 以下、略
        }
    
[/code]

  2. テンプレート関数内で動的に結果配列を生成しそれを返す
[code]     template<> const char* f<const char*>(const char* x, const char* y)
{

        char* z = new char[strlen(x) + strlen(y) + 1];
        strcpy(z, x);
        strcat(z, y);
        // zは呼び出し元でdeleteする必要がある。
        return z;
    }
    
[/code]

* * *

また、`rsize_t`と`size_t`の違いですが、机上で確認した限りだと、

  1. `RSIZE_MAX`という現実的な上限値が規定されている。
  2. `rsize_t`の値を返す関数は`RSIZE_MAX`を超える結果の場合`0`を返すことができる。

という違いがあるように見えました。  
ただし、これはC言語の規格(「C11」の規格)であり、C++言語では規格化されていないように見えましたので、コンパイラ(処理系)によっては対応していないかも知れません。


CC BY-SA 4.0
2018-09-16T16:31:49.580
48466
2018-09-17T07:31:49.513
2018-09-17T07:31:49.513
20098
20098
48465
answer