在运行时选择适当的专用模板 [英] choosing appropriate specialized template at runtime

查看:55
本文介绍了在运行时选择适当的专用模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用来自第三方库的类,

I am using a class from a 3rd party library which look like,

template <typename A = DefaultT, typename B = DefaultT, typename C = DefaultT, typename D = DefaultT, typename E = DefaultT, typename F = DefaultT>
class Vertex {};

我想在运行时根据条件使用此类的部分特化,例如,

I want to use a partial specialization of this class at runtime depending on conditions, for example,

class MyA {};
class MyB {};
class MyC {};
class MyD {};
bool useA, useB, useC, useD; //these booleans change at runtime
// I want to specialize Vertex depending on the above booleans
// The below line shouldn't compile, this is just to give an idea
typedef typename Vertex <useA ? MyA : DefaultT,  useB ? MyB : DefaultT,  
                         useC ? MyC : DefaultT,  useD ? MyD : DefaultT> MyVertex;

我想有条件地选择我要专门研究的模板参数。
我不确定是否有这个问题的名词,我怀疑这是一种多派遣的形式。

I want to conditionally choose which template arguments I want to specialize. I am not sure if there's a term for this problem, I doubt it's a flavor of multiple dispatch.

一种简单的方法是写15(2 ^ 4 -1)类,例如

A simple way would be to write 15 (2^4 -1) classes like,

typedef typename Vertex <MyA> MyVertexWithA;
typedef typename Vertex <DefaultT, MyB> MyVertexWithB;
typedef typename Vertex <MyA, MyB> MyVertexWithAB; //and so on...until
typedef typename Vertex <MyA, MyB, MyC, MyD> MyVertexWithABCD;

问题变得更加复杂,因为我必须使用使用专用顶点类的'Mesh'类

The problem becomes more complicated because I have to use a 'Mesh' class which uses the specialized vertex class

template <typename VertexClass, typename Others>
class Mesh {};

现在,如果我走了写15个类的道路,那么我将不得不再写15行每个不同的网格类型。在使用Mesh类的地方,情况变得越来越复杂。

Now if I went down the path of writing 15 classes then I would have to write 15 more lines for each different mesh type. And it keeps getting more complicated where Mesh class is used.

我坚信这必须由我或编译器来完成。我的问题:

I strongly believe this has to be done by either me or the compiler. My questions:


  1. 我想知道是否有一种方法可以使编译器为我完成这项工作?

  2. C ++ 11是否有更好的机制来处理这种情况?
    谢谢。


推荐答案

答案是否定的。如果条件在运行时发生变化,那么您将无法基于这些条件来专门化/实例化模板,它们必须是常量表达式(毕竟,编译器会在编译器运行时执行该工作, 之前) ,因此使用运行时表达式是不行的)。如果它们是在编译时确定的,则可以将 constexpr 技巧与 std :: conditional

The answer is NO. If the conditions change at runtime, then you cannot specialize/instantiate templates based on those conditions, they need to be constant expressions (after all, the compiler performs this work at compiler time, before the program starts running, so using run-time expressions is a no-no). If they are determined at compile time, then you can use constexpr tricks in combination with std::conditional.

@ Karloy Horvath提到,您还可以执行名为标签分发的操作,类似于以下示例:

As @Karloy Horvath mentioned, you can also do something called tag dispatching, similar to the example below:

#include <iostream>

struct tag_yes{};
struct tag_no{};

template <typename T> void f_tag();

template <> 
void f_tag<tag_yes>() // specializations 
{
    std::cout << "YES" << std::endl;
}

template <> 
void f_tag<tag_no>()
{
    std::cout << "NO" << std::endl;
}

void f(bool condition)
{
    if(condition)
        f_tag<tag_yes>(); // call the YES specialization
    else
        f_tag<tag_no>(); // call the NO specialization
}

int main()
{
    bool condition = true;
    f(condition); // dispatch to the "right" template function
}

或者,您甚至可以推断出标签(这就是标准C ++算法与各种迭代器类型一起使用的方式)

or, you can even deduce the tag (that's how standard C++ algorithms work with various iterator types)

#include <iostream>
#include <type_traits>

struct Foo
{
    using tag = std::true_type;
};

struct Bar
{
    using tag = std::false_type;
};

template <typename T> void f_tag();

template <> 
void f_tag<std::true_type>() // specializations 
{
    std::cout << "YES" << std::endl;
}

template <> 
void f_tag<std::false_type>()
{
    std::cout << "NO" << std::endl;
}

template <typename T>
void f(const T&)
{
        f_tag<typename T::tag>(); // dispatch the call
}

int main()
{
    Foo foo;
    Bar bar;

    f(foo); // dispatch to f_tag<std::false_type>
    f(bar); // dispatch to f_tag<std::true_type>
}

但是,在您的情况下,通过工厂可以实现多态方法和通用的虚拟接口。

However, in your case polymorphism is probably the way to go, via a factory method and a common virtual interface.

这篇关于在运行时选择适当的专用模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆