假设我正在尝试使用Curiously Recurring Template Pattern创建自己的 boost::filesystem::path 实现:
(为简洁起见,代码不完整,但在使用 ' ' 编译时会出现问题g++ -std=c++11 -o mypath ./mypath.cpp
,使用 GCC 4.8.4)
mypath.hpp:
#ifndef MYPATH_HPP
#define MYPATH_HPP
#include <string>
#include <vector>
namespace my {
template <class T>
class PathBase
{
public:
PathBase();
PathBase(std::string const& p);
std::string String() const;
bool IsSeparator(char c) const;
std::string Separators() const;
typedef std::vector<std::string> pathvec;
protected:
pathvec _path;
private:
virtual std::string _separators() const =0;
};
class Path : public PathBase<Path>
{
public:
Path();
Path(std::string const& p);
private:
virtual std::string _separators() const final;
};
} // namespace 'my'
#endif // MYPATH_HPP
我的路径.cpp:
#include "mypath.hpp"
namespace my {
//////////template class PathBase<Path>;
template<>
bool PathBase<Path>::IsSeparator(char c) const
{
return (Separators().find(c) != std::string::npos);
}
template <>
std::string PathBase<Path>::Separators() const
{
return _separators();
}
} // namespace
int main(int argc, char** argv)
{
return 0;
}
当然,我发现编写的代码不会编译,因为我在隐式实例化它Separators()
之后明确地专门化了它。IsSeparator()
但我并不是特别想玩打地鼠的游戏,试图让我所有的方法都井井有条。
在研究关于 SO 的类似问题时,我发现其中一个接受的答案表明我可以通过仅仅声明我的专业来巧妙地解决这个问题。但...
- 我在 mypath.cpp 中注释掉的
template class PathBase<Path>;
行对问题没有影响,并且 - 感觉就像我的头文件已经用它的整个
class Path : public PathBase<Path> { ... }
声明声明了显式特化。
我的显式声明到底需要是什么样的?