具有模板成员功能的Pimpl Idiom [英] Pimpl Idiom with template member function
问题描述
我想使用Pimpl Idiom,但是我遇到一个问题,成员函数之一是模板函数,因此必须在头文件中实现.
I want to use the Pimpl Idiom but I'm having a problem that one of the member functions is template function so it has to be implemented in a header file.
例如,下面的示例当然可以正常工作
For example this below works fine of course
//Foo.h
class Foo{
struct Impl;
Impl* ptr;
public:
Foo();
void bar(int);
~Foo();
};
//Foo.cpp
struct Foo::Impl{
void bar(int i){ std::cout << "i = " << i << std::endl; }
};
Foo::Foo() : ptr{new Impl}{}
void Foo::bar(int i){ ptr->bar(i); }
Foo::~Foo(){ delete ptr; }
但是如果bar
是模板函数,有什么方法可以实现类似的功能?
but is there any way to implement something similar if bar
is a template function?
//Foo.h
class Foo{
struct Impl;
Impl* ptr;
public:
Foo();
template<typename T>
void bar(T);
~Foo();
};
template<typename T>
void Foo::bar(T val)
{
/*has to be implemented in a header but I cant call member function
on an incomplete type*/
ptr->bar(val); //error
}
//Foo.cpp
struct Foo::Impl{
template<typename T>
void bar(T val){ std::cout << "val = " << val << std::endl; }
};
//...
编辑
在阅读了萨胡(R Sahu)的回答并看了所有其他评论之后,我发现自己做了建议的事情. .cpp文件中的显式模板实例化似乎是最清晰的选项,因此如果有人感兴趣,请参见以下代码.感谢所有回答!
After reading R Sahu's answer and by the looks of all the other comments I figured to do something like it was suggested to me. Explicit template instantiation in a .cpp file seemed like the most clearest option so here is the code if anyone is interested. Thanks to everyone who answered!
//Foo.h
class Foo{
struct Impl;
Impl* ptr;
public:
Foo();
template<typename T>
void bar(T);
~Foo();
};
//Foo.cpp
struct Foo::Impl{
template<typename T>
void bar(T val){ std::cout << "val = " << val << std::endl; }
};
template<typename T>
void Foo::bar(T val)
{
ptr->bar(val);
}
Foo::Foo() : ptr{ new Impl}{}
Foo::~Foo(){ delete ptr; }
#define instantiate_template_function(type)\
template void Foo::bar(type);
instantiate_template_function(int)
instantiate_template_function(double)
instantiate_template_function(char)
instantiate_template_function(float)
instantiate_template_function(long long)
推荐答案
您可以实现
template<typename T>
void bar(T);
仅当T
限于一组已知类型时,
作为成员函数.在这种情况下,您可以使用一组private
成员函数,这些成员函数使用标签struct重载.
as a member function only if T
is limited to a set of known types. In that case, you can use a set of private
member functions that are overloaded using a tag struct.
class Foo
{
template <typename T> struct Tag {};
public:
Foo();
template<typename T>
void bar(T val)
{
bar(val, Tag<T>{});
}
~Foo();
private:
struct Impl;
Impl* ptr;
void bar(int val, Tag<int> tag);
void bar(double val, Tag<double> tag);
// etc.
// Implement them in the .cpp file.
};
鉴于成员函数模板只能用于一组已知类型,您最好对其进行重载.
Given that the member function template can only be good for a known set of types, you might as well overload them.
class Foo
{
public:
Foo();
void bar(int val);
void bar(double val);
// etc.
~Foo();
private:
struct Impl;
Impl* ptr;
};
这篇关于具有模板成员功能的Pimpl Idiom的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!