gpt4 book ai didi

c++ - 具有一些非公共(public)部分的模板函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:25:08 25 4
gpt4 key购买 nike

我怀疑我可能会因为 OT 而受到指责,请原谅我。 -以防万一-

我有一个小问题,我觉得它比真正的编程问题更哲学,但仍然让我不舒服,我希望得到一些专家的意见。

让我们假设我们正在使用一个模板函数,它对所有可能的类型都有几乎相同的行为T它被允许操纵:

//Perform the rendering
template< typename T >
long drawing_facility::render( typename object_cnt< T >::type& elements, draw_type type )
{
....
//Any computation needed?
if( !obj->render_init_done.test_and_set( std::memory_order::memory_order_acquire ) )
{
....
}
....
}

在这段代码中,我跳过了所有我认为不必要的部分,除了 if。陈述。 if检查所处理对象中的原子标志,以确定是否需要对其进行特殊的“计算”,如果需要,则必须在继续“常见”任务之前完成某些操作。

我的问题是 render是一个模板,应该以相同的方式对所有可能和允许的行为表现 T , 但以防万一 render_init_done设置为 false 需要做一些不同的事情,if 中的代码并非所有 T 都通用秒。

我通过向模板添加第二个参数很快解决了这个问题,这个参数告诉代码模板正在处理哪种类型,并在此基础上在 if 中执行不同的操作。 .

我真的怀疑这不是解决问题的最优雅的方法,你对如何以不同的方式管理这个功能有什么意见吗?

我想避免大量的重复和太多的函数调用,像这样的东西应该可以完成工作:

//Perform the rendering
template< typename T >
long drawing_facility::render( typename object_cnt< T >::type& elements, draw_type type )
{
render_part_a< T >( elements );
//Any computation needed?
if( !obj->render_init_done.test_and_set( std::memory_order::memory_order_acquire ) )
{
...
}
render_part_b< T >( elements );
}

//Perform the rendering, part a
template< typename T >
long drawing_facility::render_part_a( typename object_cnt< T >::type& elements )
{
...
}

//Perform the rendering, part b
template< typename T >
long drawing_facility::render_part_b( typename object_cnt< T >::type& elements )
{
...
}

但这是解决问题的更好方法吗?现在调用render暗示另外两个函数调用,这应该不是很多,直到我可以保证 render_part_a 的独立性。和 render_part_b ,实际上我可以,但只能使用一些肮脏的技巧和微妙的参数传递解决方法。

谢谢

小更新:根据@Nim 的建议,我认为可以使用一些重载函数来解决问题,请看一下这个非常基本的示例,其中我从 render 中删除了第二个参数——不再需要了——:

typedef enum draw_type {
draw_text = 0,
draw_vertex = 1
} draw_type;

class drawable
{
public:
virtual void foo() = 0;
};

class text : drawable
{
public:
void foo() {};
};

class vertex : drawable
{
public:
void foo(){};
};

template< typename T >
class drawable_object
{ };

template< typename T >
struct object_cnt
{
typedef std::vector< std::shared_ptr< drawable_object< T > > > type;
};

class drawing_facility
{
void special( drawable_object< text >* obj )
{
std::cout<<"text\n";
}
void special( drawable_object< vertex >* obj )
{
std::cout<<"vertex\n";
}
public:
template< typename T >
long render( typename object_cnt< T >::type& elements )
{
//...
for( auto obj : elements )
{
//...
//the 'if' statement should be here.
special( obj.get() );
//...
}
//...
}
};

int main()
{
typename object_cnt< text >::type a;
a.push_back( shared_ptr< drawable_object< text > >() );
typename object_cnt< vertex >::type b;
b.push_back( shared_ptr< drawable_object< vertex > >() );
drawing_facility draw;
draw.render< text >( a );
draw.render< vertex >( b );
}

希望代码足够清晰。

最佳答案

你采用的第二种策略对我来说没有意义......

我确实会使用您原来的方法,但是对于专门的计算,例如,为每个 T 重载一个函数..

struct A{}; struct B{}; struct C{};

void compute(A& obj)
{
// code for A
}

void compute(B& obj)
{
// code for B
}

void compute(C& obj)
{
// code for C
}

template <typename T>
void render(T& obj)
{
.. // common stuff

if (!obj.computed())
{
// now call overloaded function
compute(obj);
}

.. // common stuff
}

关于c++ - 具有一些非公共(public)部分的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20514699/

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