c++ 98:根据成员的存在提供不同的函数实现

C++98: Provide different function implementations, depending on the existance of a member

本文关键字:函数 实现 存在 成员 c++      更新时间:2023-10-16

Setup:存在一个类classA和一个正在使用classA的类classB。不幸的是,在编程classB时,我不知道classA是否会有某个成员someMember。根据这一点,classB中的成员函数someFunction应该以一种或另一种方式实现。由于一种方法是使用someMember,因此在someMember不是classA 的成员的情况下,不编译该函数实例很重要。

问题:除了宏/定义之外,c++ 98中最好的解决方案是什么?

兆瓦:

class classA
{
public:
    // c'tor
    classA()
    {
        //someMember = 3;
    };
    // does not have the member "someMember"
    //int someMember;
};
class classB
{
public:
    // only compile this function if "someMember" is a member of classB
    int someFunction(classA a)
    {
        return a.someMember;
    }
    // ...and compile this one otherwise
    int someFunction(classA a)
    {
        return 2;
    }
};
// --- just to have an MWE: ---
#include<iostream>
int main()
{
    classA a;
    classB b;
    cout << b.someFunction(a);
    return 0;
}

由于您的问题被标记为templates,我认为您的classB实际上可以是一个类模板,或者至少可以使用一个…如果是这种情况,您可以应用SFINAE,例如使用以下解决方案:

#include <iostream>
#include <type_traits>
class classA
{
public:
    // c'tor
    classA()
    {
        someMember = 3;
    };
    // does not have the member "someMember"
    int someMember;
};
template<class T, class = void>
class classB_impl
{
public:
    // ...and compile this one otherwise
    int someFunction(T)
    {
        return 2;
    }
};
template <class T>
class classB_impl<T, decltype(std::declval<T>().someMember, void())> {
public:
    // only compile this function if "someMember" is a member of classB
    int someFunction(T a)
    {
        return a.someMember;
    }
};
using classB = classB_impl<classA>;
int main() {
   classB b;
   std::cout << b.someFunction(classA{}) << std::endl;
}
(现场演示)


在这种情况下(如果你正在使用c++98),你可能会更幸运地尝试使用额外的trait,例如:

#include <iostream>
class classA
{
public:
    // c'tor
    classA()
    {
        someMember = 3;
    };
    // does not have the member "someMember"
    int someMember;
};
template <class T, int T::*V = &T::someMember>
struct someMemberTrait {
    typedef void type;
};
template<class T, class = void>
class classB_impl
{
public:
    // ...and compile this one otherwise
    int someFunction(T)
    {
        return 2;
    }
};
template <class T>
class classB_impl<T, typename someMemberTrait<T>::type> {
public:
    // only compile this function if "someMember" is a member of classB
    int someFunction(T a)
    {
        return a.someMember;
    }
};
typedef classB_impl<classA> classB;
int main() {
   classB b;
   std::cout << b.someFunction(classA()) << std::endl;
}
(现场演示)