gpt4 book ai didi

c++ - 整理私有(private)函数的元编程技巧

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:35:52 24 4
gpt4 key购买 nike

这是一个关于 C++ 编译时内省(introspection)的问题

是否有已知的技巧来检测匹配函数实际上是私有(private)的,因此不能被调用?我的直觉猜测是不可能——但也许我错了?


说明:使用元编程技术(主要基于 SFINAE 机制),可以检测作为模板参数给定的类型(即我们知道该类型)中是否存在属性(嵌套类型、成员、具有特定签名的函数)存在,但我们对该类型一无所知)。基于此类内省(introspection)谓词,可以创建专门的实现、适配器等。

现在的特殊之处在于,这样的谓词可能匹配类的私有(private)成员。当我们随后根据该(错误)匹配的结果生成代码时,编译失败,因为我们实际上不允许访问该成员。因此,一种解决此类错误匹配的技术会很好......

最佳答案

好吧,我从不使用它。这只是一个想法。

因此,要检测函数是否存在,我们需要这样的东西:

#include <iostream>

#define DEFINE_METHOD_CHECKER(RETURN_TYPE, METHOD_NAME, PARAMETERS) \
template<typename T> \
struct Is ## METHOD_NAME ## MemberFunctionExists \
{ \
private: \
typedef char True; \
typedef char (&False)[2]; \
template<typename U, RETURN_TYPE (U::*)PARAMETERS = &U::METHOD_NAME>\
struct Checker \
{ \
typedef True Type; \
}; \
template<typename U> \
static typename Checker<U>::Type Tester(const U*); \
static False Tester(...); \
public: \
enum { value = (sizeof(Tester(static_cast<const T*>(0))) == sizeof(True)) }; \
}

// IsMethodMemberFunctionExists<T>::value
DEFINE_METHOD_CHECKER(int, Method, (bool));
// IsTestMemberFunctionExists<T>::value
DEFINE_METHOD_CHECKER(int*, Test, (int&, char));

class Exists
{
public:
int Method(bool);
int* Test(int&, char);
};

class NotExists
{
};

int main()
{
std::cout << IsMethodMemberFunctionExists<Exists>::value << std::endl;
std::cout << IsTestMemberFunctionExists<Exists>::value << std::endl;

std::cout << IsMethodMemberFunctionExists<NotExists>::value << std::endl;
std::cout << IsTestMemberFunctionExists<NotExists>::value << std::endl;
}


Output:
1
1
0
0

Live

很好。如果我将评论 public: - 函数将是私有(private)的,我们的检测器将打印 0 - 这样的成员函数不存在(“违反访问控制会导致替换C++11 中的失败。” 正如@T.C. 所说:

class Exists
{
//public:
int Method(bool);
int* Test(int&, char);
};

Output:
0
0
0
0

Live

现在,要检测如果给定函数是私有(private)的,我们将通过抽象类将其设为公共(public)。简而言之:

struct ITest
{
virtual void foo() = 0;
};

class Test : ITest
{
// foo() is private AND it's override Itest::foo() !
void foo();
}

// std::is_abstract<Test>() yields false !

所以,一起

#define DEFINE_PRIVATE_METHOD_CHECKER(RETURN_TYPE, METHOD_NAME, PARAMETERS) \
DEFINE_METHOD_CHECKER(RETURN_TYPE, METHOD_NAME, PARAMETERS); \
template<typename T> \
struct IsPrivate ## METHOD_NAME ## MemberFunctionExists \
{ \
public: \
struct IOverrideTest \
{ \
virtual RETURN_TYPE METHOD_NAME PARAMETERS = 0; \
}; \
\
class OverrideTest : T, IOverrideTest {}; \
\
public: \
enum { value = !IsMethodMemberFunctionExists<T>::value && !std::is_abstract<OverrideTest>::value }; \
}

// IsPrivateMethodMemberFunctionExists<T>::value
DEFINE_PRIVATE_METHOD_CHECKER(int, Method, (bool));

#include <iostream>

class PrivateExists
{
private:
int Method(bool);
int* Test(int&, char);
};

class NotExists
{
};

int main()
{
std::cout << IsPrivateMethodMemberFunctionExists<PrivateExists>::value << std::endl;
std::cout << IsMethodMemberFunctionExists<PrivateExists>::value << std::endl;

//std::cout << IsPrivateMethodMemberFunctionExists<NotExists>::value << std::endl;
//std::cout << IsMethodMemberFunctionExists<NotExists>::value << std::endl;
}

代码看起来是合法的,但是:

Clang Live将产生预期的输出:

1
0

gcc Live :

0
0

VC++ Live编译它。

嗯……下一段代码没有注释,事情变得很奇怪:

int main()
{
std::cout << IsPrivateMethodMemberFunctionExists<PrivateExists>::value << std::endl;
std::cout << IsMethodMemberFunctionExists<PrivateExists>::value << std::endl;

std::cout << IsPrivateMethodMemberFunctionExists<NotExists>::value << std::endl;
std::cout << IsMethodMemberFunctionExists<NotExists>::value << std::endl;
}

Clang Live :

1
0
1
0

gcc Live

0
0
0
0

更新:我在覆盖方面犯了一个错误:

class Exists
{
void foo();
};

struct ITest
{
virtual void foo() = 0;
};

class TestExists : Exists, ITest
{
};

TestExists 不会覆盖 foo(),所以它仍然是抽象的。解决方案是错误的。 Bu 编译器结果很有趣...

关于c++ - 整理私有(private)函数的元编程技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29709037/

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