类中存在的成员的模板实例化检查 [英] template instantiation check for member existing in class

查看:113
本文介绍了类中存在的成员的模板实例化检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组类,有一个或多个类型memberA,memberB,memberC的成员。不是所有的类都有所有的成员。我想创建一个模板来设置

I have a group of classes that have one or more members of the type memberA, memberB, memberC. Not all classes have all the members. I want to create a template that will set the members such as

template <typename T>
void setAttributes(t & myClass, typeA memA, typeB memB, typeC memC)
{
  myClass.memberA = memA;
  myClass.memberB = memb;
  myClass.memberC = memC;
}

显然,当试图实例化一个缺少的类其中一个成员。是否有一个#if或类似的东西,将允许检查完成的形式的条件编译

Obviously this will fail at compile time when attempting to instantiate a class that is missing one of the members. Is there a #if or something similar that will allow the check to be done for a conditional compile of the form

#ifdef myClass.memberA
  myClass.memberA = memA;
#endif



我现在没有访问权限,我想知道是否有一个有效的设置方法。

I do not have access right now to actually try this or anything similar and I would like to know if there is a valid way of setting it up.

我已经看到对SFINAE的引用(替换失败不是一个错误。我不知道如何将在这种情况下使用。下面的建议是否正确?

I have seen references to SFINAE ("substitution failure is not an error.") but I am not sure how it would be used in this case. Is the suggestion below correct?

替换失败不是一个错误示例似乎暗示我应该为没有该成员的重复函数的每个成员创建一个单独的函数。

Substitution failure is not an error example would seem to imply that I should create a separate function for each member with a duplicate function without that member.

template <typename T>
void setMemberA(T & myClass, typeA memA)
{
  myClass.memberA = memA;
}

template <typenum T>
void setMemberA(T & myClass)
{
  // This is a dummy template to avoid a compilation problem
}


推荐答案

这里有一个可能的 set_memberA_ifists 实现:

Here's a possible set_memberA_if_exists implementation:

namespace details {
    template<class T>
    auto set_memberA_if_exists_impl(T & myClass, typeA memA, int) 
         -> decltype(myClass.memberA = memA, void()) {
        myClass.memberA = memA;
    }

    template<class T>
    void set_memberA_if_exists_impl(T & myClass, typeA memA, long) {}
}

template<class T>
void set_memberA_if_exists(T & myClass, typeA memA) {
     details::set_memberA_if_exists_impl(myClass, memA, 0);
}

说明:

SFINAE仅适用于函数模板的签名,而不是正文,所以诀窍是对函数模板签名内的检查进行编码。这很容易使用C ++ 11结尾返回类型 - - > decltype(myClass.memberA = memA,void())。如果表达式 myClass.memberA = memA 无法编译,那么会导致替换失败,并从重载集中删除函数模板。因此,在 set_memberA_if_exists_impl 的调用仍将编译,在这种情况下,我们还提供另一个无用的重载。

SFINAE applies only to the signature, not the body, of the function template, so the trick is to encode the check inside the function template signature. This is easy using a C++11 trailing return type - -> decltype(myClass.memberA = memA, void()). If the expression myClass.memberA = memA would not compile, then it causes a substitution failure and removes the function template from the overload set. So that a call to set_memberA_if_exists_impl will still compile in that case, we also provide another do-nothing overload.

我们还需要一种方法来区分这两个重载,当它们都可行时。这通过引入第三参数来完成。 do-something重载的第三个参数的类型是 int ,而无用的重载是 long 。通过提供 0 (一个 int )作为第三个参数,我们确保do-重载是可行的。

We also need a way to distinguish between those two overloads when they are both viable. This is done by introducing a third parameter. The do-something overload's third parameter's type is int, while the do-nothing overload's is long. By providing 0 (an int) as the third argument when we call it, we make sure that the do-something overload is preferred when it is viable.

这篇关于类中存在的成员的模板实例化检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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