c++ - Type Erasure setup C++中的内部类找不到Friend函数
问题描述
我观看了 Klaus Iglberger 在 CppCon 2021 上关于类型擦除的精彩演讲。我根据他的示例自己设置了模式。他的 External Polymorphic 片段被分派给外部类的友元函数。那篇文章不适合我。
我尝试过改变定义的顺序并将友元函数的实现拉到类之外。我还没有设置实现文件,因为我不太相信这会是一个解决方案。
我正在使用 GCC 9.3 和 Clang 10。错误看起来相同。铿锵10:
type_erasure_example.cpp:57:22: error: too many arguments to function call, expected 0, have 1 serialize( object );
type_erasure_example.cpp:61:28: error: too many arguments to function call, expected 2, have 3 draw( object, x, y );
GCC9.3:
type_erasure_example.cpp:57:11: error: no matching function for call to ‘Shape::ShapeModel<Square>::serialize(const Square&) const’ 57 | serialize( object );
type_erasure_example.cpp:61:11: error: no matching function for call to ‘Shape::ShapeModel<Square>::draw(const Square&, int&, int&) const’ 61 | draw( object, x, y );
#include <iostream>
#include <memory>
#include <vector>
class Circle
{
public:
explicit Circle( double rad )
: radius{ rad }
// ... Remaining data members
{}
double getRadius() const noexcept { return radius; }
// ... getCenter(), getRotation(), ...
private:
double radius;
// ... Remaining data members
};
class Square
{
public:
explicit Square( double s )
: side{ s }
// ... Remaining data members
{}
double getSide() const noexcept { return side; }
// ... getCenter(), getRotation(), ...
private:
double side;
// ... Remaining data members
};
class Shape
{
private:
struct ShapeConcept
{
virtual ~ShapeConcept() {}
virtual void serialize() const = 0;
virtual void draw(int x, int y) const = 0;
virtual std::unique_ptr<ShapeConcept> clone() const = 0;
};
template< typename T >
struct ShapeModel : ShapeConcept
{
ShapeModel( T&& value )
: object{ std::forward<T>(value) }
{}
std::unique_ptr<ShapeConcept> clone() const override
{
return std::make_unique<ShapeModel>(*this);
}
void serialize() const override
{
serialize( object ); // Error
}
void draw( int x, int y ) const override
{
draw( object, x, y ); // Error
}
T object;
};
friend void serialize( Shape const& shape )
{
shape.pimpl->serialize();
}
friend void draw( Shape const& shape, int x, int y )
{
shape.pimpl->draw( x, y );
}
std::unique_ptr<ShapeConcept> pimpl;
public:
template< typename T >
Shape( T&& x )
: pimpl{ new ShapeModel<T>( std::forward<T>(x) ) }
{}
// Special member functions
Shape( Shape const& s );
Shape( Shape&& s );
Shape& operator=( Shape const& s );
Shape& operator=( Shape&& s );
};
void serialize( Circle const& circle ) {
std::cout << "Serializing a circle with radius "
<< circle.getRadius() << std::endl;
}
void draw( Circle const& circle, int x, int y ) {
std::cout << "Drawing a circle with radius "
<< circle.getRadius() << " Coordinates ("
<< x << ", " << y << ")" << std::endl;
}
void serialize( Square const& square ) {
std::cout << "Serializing a square with side "
<< square.getSide() << std::endl;
}
void draw( Square const& square, int x, int y ) {
std::cout << "Drawing a square with side "
<< square.getSide() << " Coordinates ("
<< x << ", " << y << ")" << std::endl;
}
void drawAllShapes( std::vector<Shape> const& shapes )
{
for( auto const& shape : shapes )
{
draw( shape , 0.0, 0.0 );
}
}
int main()
{
using Shapes = std::vector<Shape>;
// Creating some shapes
Shapes shapes;
shapes.emplace_back( Circle{ 2.0 } );
shapes.emplace_back( Square{ 1.5 } );
shapes.emplace_back( Circle{ 4.2 } );
// Drawing all shapes
drawAllShapes( shapes );
}
解决方案
有人在评论中发帖,这让我走上了正轨。我对设置不够了解。朋友班得到了正确的处理。需要重新安排的是免费功能。一个实现文件毕竟会有所帮助,我们可以只做标题:
#include <iostream>
#include <memory>
#include <vector>
class Circle
{
public:
explicit Circle( double rad )
: radius{ rad }
// ... Remaining data members
{}
double getRadius() const noexcept { return radius; }
// ... getCenter(), getRotation(), ...
private:
double radius;
// ... Remaining data members
};
class Square
{
public:
explicit Square( double s )
: side{ s }
// ... Remaining data members
{}
double getSide() const noexcept { return side; }
// ... getCenter(), getRotation(), ...
private:
double side;
// ... Remaining data members
};
void serialize( Circle const& circle ) {
std::cout << "Serializing a circle with radius "
<< circle.getRadius() << std::endl;
}
void draw( Circle const& circle, int x, int y ) {
std::cout << "Drawing a circle with radius "
<< circle.getRadius() << " Coordinates ("
<< x << ", " << y << ")" << std::endl;
}
void serialize( Square const& square ) {
std::cout << "Serializing a square with side "
<< square.getSide() << std::endl;
}
void draw( Square const& square, int x, int y ) {
std::cout << "Drawing a square with side "
<< square.getSide() << " Coordinates ("
<< x << ", " << y << ")" << std::endl;
}
class Shape
{
private:
struct ShapeConcept
{
virtual ~ShapeConcept() {}
virtual void serialize() const = 0;
virtual void draw(int x, int y) const = 0;
virtual std::unique_ptr<ShapeConcept> clone() const = 0;
};
template< typename T >
struct ShapeModel : ShapeConcept
{
ShapeModel( T&& value )
: object{ std::forward<T>(value) }
{}
std::unique_ptr<ShapeConcept> clone() const override
{
return std::make_unique<ShapeModel>(*this);
}
void serialize() const override
{
::serialize( object );
}
void draw( int x, int y ) const override
{
::draw( object, x, y );
}
T object;
};
friend void serialize( Shape const& shape )
{
shape.pimpl->serialize();
}
friend void draw( Shape const& shape, int x, int y )
{
shape.pimpl->draw( x, y );
}
std::unique_ptr<ShapeConcept> pimpl;
public:
template< typename T >
Shape( T&& x )
: pimpl{ new ShapeModel<T>( std::forward<T>(x) ) }
{}
// Special member functions
Shape( Shape const& s ) = default;
Shape( Shape&& s ) = default;
Shape& operator=( Shape const& s ) = default;
Shape& operator=( Shape&& s ) = default;
};
void drawAllShapes( std::vector<Shape> const& shapes )
{
for( auto const& shape : shapes )
{
draw( shape , 0.0, 0.0 );
}
}
int main()
{
using Shapes = std::vector<Shape>;
// Creating some shapes
Shapes shapes;
shapes.emplace_back( Circle{ 2.0 } );
shapes.emplace_back( Square{ 1.5 } );
shapes.emplace_back( Circle{ 4.2 } );
// Drawing all shapes
drawAllShapes( shapes );
}
推荐阅读
- python - python cmd中的中心输入?
- android - Flutter:升级Play商店的版本代码
- python - /signup/create_user() 处的 Django TypeError 缺少 1 个必需的位置参数:“用户名”
- angular - 在 Ionic 3 中打开键盘时隐藏元素
- excel - 通过vb检查路径文件夹
- android-studio - 从 AdColony 请求广告时出现 jni_onload 错误
- node.js - 什么是 Dialogflow 对话?使用 node.js Fulfillment SDK
- node.js - 如何使用节点 js 创建 pdf/a-1b 文件?
- javascript - 在 ionic 应用程序的 Firebase 文本中嵌入链接
- owl - 我如何表达一个对象属性是另一个对象的否定?