gpt4 book ai didi

c++ - 带有模板成员函数的 Pimpl Idiom

转载 作者:行者123 更新时间:2023-11-30 05:13:08 24 4
gpt4 key购买 nike

我想使用 Pimpl Idiom,但我遇到了一个问题,其中一个成员函数是模板函数,因此它必须在头文件中实现。

例如下面这个当然可以正常工作

//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 是一个模板函数,有什么方法可以实现类似的东西吗?

//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 文件中的显式模板实例化似乎是最清晰的选项,所以如果有人感兴趣,这里是代码。感谢所有回答的人!

//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 成员函数。

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.
};

鉴于成员函数模板只能适用于一组已知的类型,您不妨重载它们。

class Foo
{
public:
Foo();

void bar(int val);
void bar(double val);
// etc.

~Foo();

private:
struct Impl;
Impl* ptr;
};

关于c++ - 带有模板成员函数的 Pimpl Idiom,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44078373/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com