int(0)からベクター内のポインターへの暗黙的な変換を回避する方法


9

JSONでキーへのパスのすべてのノード名を収集したい状況があります。配列インデックス「0」、「1」の条件も許可されていることを考慮してください。ただし、引用符を忘れがちであり、逆参照するとクラッシュする可能性があります。これを拒否したいのですが。例:

#include <vector>
#include <iostream>

int func(const std::vector<const char*>& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

私はこれを見つけて試してみました非構築関数の暗黙的な変換をどのように回避しますか?次のように:

#include <vector>
#include <iostream>

int func(const std::vector<const char*>& pin) {
    return pin.size();
}

template<typename T>
int func(T pin) = delete;

int main() {
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

しかし、コンパイラはまだ私を理解していませんでした。

なにか提案を?
用語や仮定の誤用を指摘してください、ありがとうございます!


std::vector<const char*>代わりに使用する理由はありますstd::vector<std::string>>か?
ボロフ

あなたnullptrも禁止したいですか?
Jarod42

@bolov最初に、これらのノード名をJSON分析インターフェースに渡すことを検討します。JSON分析インターフェースは、Cスタイルのchar *を入力として使用しますが、これはここに限定されません。std :: vector <std :: string >>を使用してテストしましたが、コンパイル時に0を受け入れますが、実行時にクラッシュします。私のマシンでGCCは「basic_string :: _ M_construct null not valid」と報告します。
rustyhu

@ Jarod42はい、必要なのはCスタイルの文字列リテラルです。
rustyhu

回答:


9

このようなもの?これは、提案したオーバーロードソリューションに非常に似ていますが、ベクタータイプをラップする必要があります。0削除されたコンストラクターオーバーロードが選択されているため、リテラルを指定するとビルドに失敗します。

#include <memory>
#include <new>
#include <vector>
#include <iostream>
using std::vector;

template<typename T>
struct no_zero {
        no_zero(T val) : val(val) {}
        no_zero(int val) = delete;
        operator T() { return val; }
        T val;
};

int func(const vector<no_zero<const char*> >& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

4

後から見ると、C ++の暗黙的な変換の多くは残念ですが、これはそのうちの1つです。

考慮すべき1つのオプションは-Wzero-as-null-pointer-constant、gccとclangです。これにより標準プログラムの動作が変更されるため、グローバルに有効にすると意図しない影響が生じる可能性があるので注意してください。

g ++-0からポインタ型への暗黙の変換を無効にするにはどうすればよいですか?

GlangのWzero-as-null-pointer-constantに相当するClang警告はどれですか?


3

私はミケル・リクリスキの答えが好きです。ただし、ガイドラインサポートライブラリにはすでにソリューションが存在します。

gsl::not_null

GSLを強くお勧めします。多くのC ++エキスパート、Bjarne Stroustrup自身とその中のHerb Sutterによって作成され、支援されています。また、C ++コアガイドラインは、コンパイラの警告と静的アナライザーに積極的に統合されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.