ブースト以外のソリューションには、システムに依存するコード(ブーストを使用する場合は がブーストに表示されません)が含まれます。そして、正確に と定義する必要があります:"./MyFile.xxx"
と"MyFile.xxx"
は同等ですか? "aaa/.../MyFile.xxx"
と"MyFile.xxx"
はどうですか?
私はこれを処理するような方法は、2つのデータメンバを持つクラスを定義することで、 std::string
(常にUnixの内空 だろう)“接頭”と、パス のすべての要素を持つstd::vector<std::string>
。このクラスには、必要な比較 関数が含まれており、システム依存コードを使用して コンストラクタを実装します。コンストラクタ自体は、ソースファイルであろう、と ソースファイルは、一般的に使用するディレクトリを指定するための手段-I
の 又は/I
によりヘッダを各変異体のための別のディレクトリを 使用、および選択することによって(マシン依存ヘッダを含むであろう)。ヘッダーに行くかもしれないものの一種 :Unix用
inline bool
isPathSeparator(char ch)
{
return ch == '/';
}
std::string
getHeader(std::string const& fullPathName)
{
return "";
}
bool
charCompare(char lhs, char rhs)
{
return lhs < rhs;
}
bool
charMatch(char lhs, char rhs)
{
return lhs == rhs;
}
、と:Windows用
inline bool
isPathSeparator(char ch)
{
return ch == '/' || ch == '\\';
}
std::string
getHeader(std::string const& fullPathName)
{
return fullPathName.size() > 2 && fullPathName[1] == ':'
? fullPathName.substr(0, 2)
: std::string();
}
bool
charCompare(char lhs, char rhs)
{
return tolower((unsigned char)lhs) < tolower((unsigned char)rhs);
}
bool
charMatch(char lhs, char rhs)
{
return tolower((unsigned char)lhs) == tolower((unsigned char)rhs);
}
。
コンストラクタは、ヘッダを初期化するために
getHeader
を使用し
、及び要素にアップ 文字列を破壊input.begin() + header.size()
とinput.end()
超える反復、。 "."
という要素がある場合は、".."
のいずれかに対して、 を無視し、パスが空でない場合は、pop_back()
を使用して、パスの先頭の 要素を削除します。その後、それはstd::string
ため コンパレータで だけchar
ためcharCompare
と charMatch
を使用するコンパレータを定義の問題、およびstd::lexicographical_compare
または std::equal
(サイズが同じであることを確認した後)だ(そしておそらく、さらに新しい クラス用) 。次のようなもの:
struct FileNameCompare
{
bool operator()(char lhs, char rhs) const
{
return charCompare(lhs, rhs);
}
bool operator()(std::string const& lhs, std::string const& rhs) const
{
return std::lexicographical_compare(
lhs.begin(), lhs.end(),
rhs.begin(), rhs.end(),
*this);
}
bool operator()(FileName const& lhs, FileName const& rhs) const
{
return (*this)(lhs.prefix, rhs.prefix)
|| (!(*this)(rhs.prefix, lhs.prefix)
&& std::lexicographical_compare(
lhs.elements.begin(), lhs.elements.end(),
rhs.elements.begin(), rhs.elements.end(),
*this));
}
};
struct FileNameMatch
{
bool operator()(char lhs, char rhs) const
{
return charMatch(lhs, rhs);
}
bool operator()(std::string const& lhs, std::string const& rhs) const
{
return lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(), rhs.begin(), *this);
}
bool operator()(FileName const& lhs, FileName const& rhs) const
{
return (*this)(lhs.prefix, rhs.prefix)
&& lhs.elements.size() == rhs.elements.size()
&& std::equal(lhs.elements.begin(), lhs.elements.end(),
rhs.elements.begin(),
*this);
}
};
このトリックを行う必要があります。 (ただ、operator()(char, char) const
は、ソースファイルでなければならないことを覚えておいてください。あなたは charCompare
とcharMatch
を定義するシステム依存のヘッダーは含まれません、ヘッダー、 でそれらをインライン化することはできません。)
+1良い質問です。ブーストの代替手段はありますか? – Walter
あなたは今のところヘッダー専用のブーストを使用していますが、なぜそれがlib依存関係を追加しない理由ですか? –
@Tomalak Garet'kal:Sun Studio 5.7のコンパイルでは、いくつかの問題があります。 –