【问题标题】:How can i identify if a template parameter argument is instance of another class in a struct within template? C++我如何确定模板参数参数是否是模板内结构中另一个类的实例? C++
【发布时间】:2016-05-02 18:49:40
【问题描述】:

我有一个 .h 文件,其中包含我的所有模板,还有一个 .cpp 文件,其中包含我的主文件。

.h 模板的一部分:

   template<int N, int P>
    struct BOUND {
        static inline int eval(int v) {
            //...
            return 1; 
        };
    };

    template<class K>
    struct VAL_x {
        static inline int eval(int v) {
            //...
            return 1;
        };
    };

    template<int L, class K>
    struct LIT {
        static inline int eval(int v) {
            //...
            return 1;
        };
    };

    template<class A, class B, class K>
    struct ADD {
        static inline int comp_b(int v){
            // HERE check if class A is LIT  or VAL_x
            //...
            return 2;
        };
    };

这是我在 main() 这个模板中的调用方式:

int main() {

    typedef ADD<VAL_x<BOUND<2,3> >, LIT<2, BOUND<2,3> >, BOUND<2,3> > FORM;
    FORM exec_form;

    int y = 2;

    int bounds = exec_form.comp_b(y);

    return 0;
}

我如何知道我的structADD::comp() 函数中传递的参数是否是特定类的实例(例如LIT&lt;&gt;)?这些参数可以按任何顺序传递(例如,所有参数都可以是LIT,或者只有第二个)

注意:除了VAL_xLITBOUNDADD之外,还有其他结构。

【问题讨论】:

  • 您的意思是模板中的参数对吧?不是comp() 的论点。一个最小的例子在这里会很好。 :)
  • 您的示例不起作用,因为您缺少 something 的模板参数
  • @Dani 很抱歉,这是因为我试图更改名称并忘记了它......我现在将更新它以便更容易理解。
  • @gsamaras @ Dani 我已经更新了我的代码。
  • 谢谢@marialena,这个template&lt;int L&gt;的目的是什么?

标签: c++ class templates struct parameters


【解决方案1】:

选项 #1

为每个感兴趣的类模板引入一个单独的特征(C++03 在这里没有多大帮助)。

template <bool B> struct bool_constant { static const bool value = B; };
template <bool B> const bool bool_constant<B>::value;

template <typename T>   struct is_LIT : bool_constant<false> {};
template <int L, int M> struct is_LIT<LIT<L, M> > : bool_constant<true> {};

template <typename T> struct is_VAL_x : bool_constant<false> {};
template <int K>      struct is_VAL_x<VAL_x<K> > : bool_constant<true> {};

template <class A, class B>
struct ADD 
{
    static inline int comp_b(int v)
    {
        if (is_LIT<A>::value && is_VAL_x<B>::value)
        {

        }

        return 2;
    }
};

DEMO

选项 #2

使用通用的自定义特征,其特化检测传递的类型是否是指定模板模板参数的实例化(如果特化匹配,即T是类模板X的实例化):

template <template <int> class X, typename T>
struct is_template { static const bool value = false; };

template <template <int> class X, int N>
struct is_template<X, X<N> > { static const bool value = true; };

template <typename A, typename B>
struct ADD 
{
    static inline int comp_b(int v)
    {
        if (is_template<VAL_x, A>::value && is_template<LIT, B>::value)
        {
        }

        return 2;
    }
};

DEMO 2

选项#3

使用标签调度,可能为返回true/false的其他类模板添加重载,使其类似于选项#1。此解决方案还依赖于重载解决方案,它更喜欢更专业的函数模板,而不是那些限制较少/通用的。

template <typename T> struct tag {};

template <typename A, typename B>
struct ADD 
{
    static inline int comp_b(int v)
    {
        return comp_b(v, tag<A>(), tag<B>());
    }

    template <int M, int N>
    static inline int comp_b(int v, tag<LIT<M> >, tag<VAL_x<N> >)
    {
        return 1;
    }

    template <typename T, typename U>
    static inline int comp_b(int v, tag<T>, tag<U>)
    {
        return 2;
    }
};

DEMO 3

【讨论】:

  • 皮奥特,太棒了!!我不知道您是否赞成我的回答,但这更好,值得我给予更多赞成!你能解释一下你的解决方案吗?最后一个。 :)
  • 我已尝试遵循第一个选项。正如我所看到的,您的示例受到结构模板参数数量的影响。所以我已经放置了我的结构所采用的正确数量的参数。我没想到这会很重要。如果您可以向我解释您的示例是如何工作的,我可以对其进行更改以适合我的情况。改变的是ADD 带三个参数,LIT 带2 个。但是在ADD 结构中,我只想检查第一个和第二个模板参数的类。我不在乎第三个。
  • @marialena 我认为您想要实现的是模板化 AST,对吗?如果我是对的,您不需要在模板参数类型上“分支”,它们已经为更改实现提供了点,最多您必须传递一个“环境”参数来设置变量的值。
  • @DarioOO 没有 100% 肯定,我认为是的...我是 C++ 模板的新手,所以我只是想了解模板如何工作以及它们如何相互交互。
  • @DarioOO 不,不,你误会了我。这是课程的一小部分。我只是简化了代码中的细节。我只是想知道我是否可以识别参数的类。但当然,解决方案需要一个完整的示例才能应用于我的案例。对于造成的任何不便,我深表歉意。我将尝试查看 Piotr 的更新选项。谢谢你们。
【解决方案2】:

你可以这样做:

#include <typeinfo>
...
template<class A, class B>
struct ADD {

    static inline int comp_b(int v){
        // HERE check if class A is LIT  or VAL_x
        std::cout << ( typeid(A)==typeid(VAL_x) ) << '\n';
        return 2;
    };
};

我在哪里使用std::type_info,它将打印 1,以进行真正的评估。

或者,使用,您可以这样做:

#include <type_traits>
...
if (std::is_same<A, VAL_x>::value)
    std::cout << "they are same!\n";

但是,您可以重载函数等。确保你阅读了这个:How do I check my template class is of a specific classtype? 和这个How to check for the type of a template parameter?

【讨论】:

  • 我已经更新了我的代码;我的VAL_x 结构也在LIT 之类的模板中。我正在尝试在 ADD 结构中添加您建议的第一个解决方案,但 VAL_x 需要模板参数。如果是VAL_x,我知道这个论点。但在LIT 的情况下,我不知道。这是我尝试过的,但由于缺少模板参数而出错。 bool isLIT = typeid(A)==typeid(VAL_x); isLIT ? "true" : "false"; printf("%s \n", isLIT);
  • @marialena 这很有道理,不是吗? :) 这种检查是在编译时进行的,因此您也应该提供参数。例如 VAL_x 会起作用,但你说的是明天可能是 4,对吧(这不一样)?
  • 是的.. 这当然是有道理的。我在 main 中给出的公式可以是任何东西。例如,LIT 可以是第一个参数,VAL_x 可以是最后一个参数。或者两者都可以是LITVAL_x。我只想在ADD查看他们的课程。
  • @marialena,Piotr 的回答也很有道理,看看吧!!感谢您的支持。
猜你喜欢
  • 2021-12-21
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多