在 requires 子句中访问私有成员
Access private members in requires clause
考虑以下程序:
#include <iostream>
template<typename T> void f1(T& v)
{
std::cout << "f1: can call g" << std::endl;
v.g();
}
template<typename T> void f2(T& v) requires requires (T& v) { v.g(); }
{
std::cout << "f2: can call g" << std::endl;
v.g();
}
template<typename T> void f2(T&) requires (!requires (T& v) { v.g(); })
{
std::cout << "f2: cannot call g" << std::endl;
}
class A
{
public: // if commented out, f2 will not call g anymore
void g()
{
std::cout << "g called" << std::endl;
}
template<typename T> friend void f1(T& v);
template<typename T> friend void f2(T& v);
};
class B
{
};
int main()
{
std::cout << "A" << std::endl;
A a{};
f1(a);
f2(a);
std::cout << "B" << std::endl;
B b{};
f2(b);
return 0;
}
函数 g
可能存在于 class 中,也可能不存在。如果有(比如 A
),函数 f2
应该调用它,如果没有(比如 B
),它就不应该调用。这种区别是通过 requires
子句进行的。
我在 A
中与 f2
成为好友,因此它应该能够调用 g
,即使它是私有的(一般来说,与 f1
建立好友效果很好,参见 f1
)。但是,requires
似乎忽略了该函数是友善的,因此,当在 A
中将 g
设为私有时,不再调用 g
。
这是为什么?是否有解决方法,即以是否可以调用函数为条件,即使它是私有的(但已成为朋友)?甚至可能使用旧学校 std::enable_if
?
当您将一个函数或函数模板设为好友时,只有该函数的主体可以获得访问权限,而不是它的各种附件。附加到它的约束是无关紧要的。
您可以通过将检查移动到 f2
的正文中来解决此问题,以便在具有此访问权限的上下文中检查它:
template <typename T>
void f2(T& v)
{
if constexpr (requires { v.g(); }) {
std::cout << "f2: can call g\n";
v.g();
} else {
std::cout << "f2: cannot call g\n";
}
}
考虑以下程序:
#include <iostream>
template<typename T> void f1(T& v)
{
std::cout << "f1: can call g" << std::endl;
v.g();
}
template<typename T> void f2(T& v) requires requires (T& v) { v.g(); }
{
std::cout << "f2: can call g" << std::endl;
v.g();
}
template<typename T> void f2(T&) requires (!requires (T& v) { v.g(); })
{
std::cout << "f2: cannot call g" << std::endl;
}
class A
{
public: // if commented out, f2 will not call g anymore
void g()
{
std::cout << "g called" << std::endl;
}
template<typename T> friend void f1(T& v);
template<typename T> friend void f2(T& v);
};
class B
{
};
int main()
{
std::cout << "A" << std::endl;
A a{};
f1(a);
f2(a);
std::cout << "B" << std::endl;
B b{};
f2(b);
return 0;
}
函数 g
可能存在于 class 中,也可能不存在。如果有(比如 A
),函数 f2
应该调用它,如果没有(比如 B
),它就不应该调用。这种区别是通过 requires
子句进行的。
我在 A
中与 f2
成为好友,因此它应该能够调用 g
,即使它是私有的(一般来说,与 f1
建立好友效果很好,参见 f1
)。但是,requires
似乎忽略了该函数是友善的,因此,当在 A
中将 g
设为私有时,不再调用 g
。
这是为什么?是否有解决方法,即以是否可以调用函数为条件,即使它是私有的(但已成为朋友)?甚至可能使用旧学校 std::enable_if
?
当您将一个函数或函数模板设为好友时,只有该函数的主体可以获得访问权限,而不是它的各种附件。附加到它的约束是无关紧要的。
您可以通过将检查移动到 f2
的正文中来解决此问题,以便在具有此访问权限的上下文中检查它:
template <typename T>
void f2(T& v)
{
if constexpr (requires { v.g(); }) {
std::cout << "f2: can call g\n";
v.g();
} else {
std::cout << "f2: cannot call g\n";
}
}