Ich*_*hyo 4 c++ metaprogramming c++11
这是关于C++中编译时内省的问题
是否有一个已知的技巧来检测匹配函数是否实际上是私有的,因此无法调用?我的直觉猜测是这是不可能的 - 但也许我错了?
说明:使用元编程技术(主要基于SFINAE机制),可以在作为模板参数给出的类型中检测属性(嵌套类型,成员,具有特定签名的函数)的存在(即我们知道这种类型存在,但是我们对这种类型一无所知.)基于这样的内省谓词,可以创建专门的实现,适配器等.
现在具体的转折是这样的谓词可能匹配类的私有成员.当我们随后根据该(false)匹配的结果生成代码时,编译失败,因为实际上我们不允许访问该成员.因此,解决这种错误匹配的技术会很好......
好的,我从不使用它.这只是一个想法.
因此,要检测函数是否存在,我们需要这样的事情:
#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
Run Code Online (Sandbox Code Playgroud)
好.如果我要评论public:- 函数将是私有的,我们的探测器将打印0- 这样的成员函数不存在("违反访问控制会导致C++ 11中的替换失败."正如@TC所说):
class Exists
{
//public:
int Method(bool);
int* Test(int&, char);
};
Output:
0
0
0
0
Run Code Online (Sandbox Code Playgroud)
现在,要检测,如果给定的函数是私有的,我们将通过抽象类公开它.简而言之:
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 !
Run Code Online (Sandbox Code Playgroud)
#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;
}
Run Code Online (Sandbox Code Playgroud)
代码看起来合法,但是:
Clang Live将产生预期的输出:
1
0
Run Code Online (Sandbox Code Playgroud)
0
0
Run Code Online (Sandbox Code Playgroud)
VC++直播将不会编译它.
嗯..下一个代码没有发生的事情变得很奇怪:
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;
}
Run Code Online (Sandbox Code Playgroud)
1
0
1
0
Run Code Online (Sandbox Code Playgroud)
0
0
0
0
Run Code Online (Sandbox Code Playgroud)
更新:我有一个关于覆盖的错误:
class Exists
{
void foo();
};
struct ITest
{
virtual void foo() = 0;
};
class TestExists : Exists, ITest
{
};
Run Code Online (Sandbox Code Playgroud)
TestExists不会覆盖foo(),所以它仍然是抽象的.解决方案是错误的.Bu编译器的结果很有意思......
| 归档时间: |
|
| 查看次数: |
1055 次 |
| 最近记录: |