任何非 Boost 解决方案都将涉及系统相关代码(即
如果使用 Boost,则隐藏在 Boost 中)。你必须准确定义
你所说的“匹配”是什么意思:应该"./MyFile.xxx"和"MyFile.xxx"
比较相等? "aaa/.../MyFile.xxx" 和 "MyFile.xxx" 呢?
我处理这个问题的方法是定义一个有两个数据成员的类,
带有“前缀”的std::string(始终是
在 Unix 中为空),以及带有所有路径的 std::vector<std::string>
元素。这门课会被必要的比较所宠爱
功能,并会使用系统相关的代码来实现
构造函数;构造函数本身将在源文件中,并且
源文件将包含与机器相关的标头(通常通过使用
每个变体都有一个单独的目录,并通过手段选择标题
-I 或 /I 指定要使用的目录)。那种东西
这可能会进入标题:
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;
}
对于 Unix,带有:
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 );
}
适用于 Windows。
然后构造函数将使用getHeader 来初始化标头,并且
遍历input.begin() + header.size() 和input.end(),打破
串成元素。如果遇到"."的元素,
忽略它,对于".." 之一,使用pop_back() 删除顶部
路径的元素,前提是路径不为空。之后就是
只是定义比较器以使用charCompare 和
charMatch 代表 char 和 std::lexicographical_compare 或
std::equal(在验证大小相等后)与
std::string 的比较器(可能还有你的新
班级)。比如:
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.)