2

プログラムのディレクトリ構造を定数文字列の構造として保存したいのですが、C++ では直感的な方法でそれを行うことができません。

したがって、これは機能しません:

struct DirStructure {
    static const std::string entities = "./entities";
    static const std::string scripts = "./scripts";
}

これもありません:

struct DirStructure {
    static const std::string entities() const = { return "./entities"; }
    static const std::string scripts() const { return "./scripts"; }
}

(実際には const なしで実行されますが、私はあまり好きではありません)。

これは機能します:

namespace DirStructure {
    static const std::string entities = "./entities";
    static const std::string scripts = "./scripts";
}

しかし、それには他にもいくつかの問題があります。

そのような問題に対処する標準的な方法は何ですか (私がむしろ避けたいと仮定して#define MY_SCRIPTS_DIR_PATH "./scripts")?

4

3 に答える 3

3

3つのアプローチが思い浮かびます。最初の2つはあなたのアプローチに似ていますが、後者は私が使用する可能性のあるもののより典型的なものです

#1 - 匿名名前空間 + インラインconstexpr関数

これは、私の目的のために1つの問題を除くすべてを解決します:

#include <string>

namespace DirStructure {
    namespace {
        inline constexpr char const* const entities() { return "./entities"; }
    }
};

int main()
{
    std::string e = DirStructure::entities();
}

1 つ残っている問題は、文字列リテラルに NUL 文字を埋め込むことができないことです (ファイル パスの場合は問題ありません)。

#2 - 集計の初期化

別のアプローチは

#include <string>

struct DirStructure
{
    std::string entities, scripts;
};

inline static const DirStructure& Config()
{
    static DirStructure _s = { "./entities", "./scripts" };
    return _s;
}

int main()
{
    std::string e = Config().entities;
}

#3 - 表情豊かなタイプ

通常、私が実際に自分で使用するものは次のようになります。

#include <string>
#include <map>
#include <boost/filesystem.hpp>

int main()
{
    const std::map<std::string, boost::filesystem::path> DirStructure = { 
        { "entities", "./entities" },  
        { "scripts", "./scripts" } 
    };
    auto const& e = DirStructure.at("entities");
}
于 2013-03-03T12:41:23.187 に答える
2

最初のバージョンは、わずかな調整で問題なく動作するはずです。宣言を定義から分割する必要があります。

# Declaration in dirstructure.h
struct DirStructure {
    static const std::string entities;
    static const std::string scripts;
}

# Definition in dirstructure.cpp
const std::string DirStructure::entities("./entities");
const std::string DirStructure::scripts("./scripts");
于 2013-03-03T12:39:43.520 に答える
1

source.cpp:4:54: エラー: 非リテラル型の静的データ メンバー 'const string DirStructure::entities' のクラス内初期化

source.cpp:4:54: エラー: 静的メンバー 'DirStructure::entities' の非定数クラス内初期化が無効です

source.cpp:4:54: エラー: (クラス外の初期化が必要です)

g++クラス外の初期化が必要であることを示しているため、次のようになります。

struct DirStructure {
    static const std::string entities;
    static const std::string scripts;
}

const std::string DirStructure::entities = "blah";
const std::string DirStructure::scripts = "blah2";

動作します。しかし、名前空間も好みます。

于 2013-03-03T12:39:58.060 に答える