一组类型的显式实例化

问题描述 投票:2回答:3

在我的代码中,通常我必须编写一个采用“类路径”类型的函数,也就是说,我可以转换为boost::filesystem::path的函数,例如

  • QString
  • std::string
  • const char *
  • 等等...

在A.hpp

struct A
{
  template <typename PathLike> 
  void myFunction(PathLike path);
};

在A.cpp

template <typename PathLike> 
void A::myFunction(PathLike path)
{
   boost::filesystem::Path p = convertToBoostPath(path);
   //do something...
}

//Explicit instantiations needed 
template void A::myFunction(string);  
template void A::myFunction(QString);
template void A::myFunction(char const *);
//....

问题是,如果我想在不同的函数B中做同样的事情,我需要重新添加显式实例化。也许我采取了错误的做法。

c++ templates metaprogramming
3个回答
3
投票

不是编写一个接受任何PathLike的模板函数而且还能完成真正的工作,而是编写一个模板函数,它接受任何PathLike,如图所示将其转换为boost::filesystem::Path,然后调用非模板函数(其定义可以在.cpp中)这将做真正的工作。

A.hpp

class A
{
public:
  template <typename PathLike> 
  void myFunction(PathLike path);

private:
  void myFunctionImpl(boost::filesystem::Path path);
};


template <typename PathLike> 
void A::myFunction(PathLike path)
{
  myFunctionImpl(convertToBoostPath(path));
}

A.cpp

void A::myFunctionImpl(boost::filesystem::Path path)
{
  // do something...
}

这具有额外的好处,即错误使用接口会导致编译器错误,而不会导致链接器错误。


1
投票

如何创建一个类PathLike并使用它:

class PathLike
{
public:
    explicit PathLike(const QString& path) : mPath(convertToBoostPath(path)) {}
    explicit PathLike(const std::string& path) : mPath(convertToBoostPath(path)) {}
    explicit PathLike(const char* path) : mPath(convertToBoostPath(path)) {}
    PathLike(const boost::filesystem::path& path) : mPath(path) {}

    const boost::filesystem::path& get() const { return mPath;}
    operator const boost::filesystem::path&() const { return mPath;}
private:
    boost::filesystem::path mPath;
};

(我标记其他构造函数显式提升filesystem::path,但由你来添加/删除explicit)。

然后:

struct A
{
    void myFunction(PathLike path)
    {
       boost::filesystem::path p = path;
       //do something...
    }
};

0
投票

为一组类型显式实例化函数模板的一种方法是获取每个函数实例化的地址。例如。:

template<class... Ts>
void instantiate_myFunction() {
    auto f = [](auto&&) { return 1; };
    auto initializer_list = { f(&A::myFunction<Ts>)...  };
    static_cast<void>(initializer_list);
}

int main() {
    instantiate_myFunction<std::string, char const*>();
}
© www.soinside.com 2019 - 2024. All rights reserved.