C++ 如何测试方法是否为常量?

C++ 如何测试方法是否为常量?,c++,templates,c++11,typetraits,C++,Templates,C++11,Typetraits,如何获得一个布尔值,指示已知方法是否具有常量限定符 例如: struct A { void method() const {} }; struct B { void method() {} }; bool testA = method_is_const<A::method>::value; // Should be true bool testB = method_is_const<B::method>::value; // Should be fal

如何获得一个布尔值,指示已知方法是否具有常量限定符

例如:

struct A {
    void method() const {}
};

struct B {
    void method() {}
};

bool testA = method_is_const<A::method>::value; // Should be true
bool testB = method_is_const<B::method>::value; // Should be false
结构A{ void method()常量{} }; 结构B{ void方法(){} }; bool testA=方法是常量::值;//应该是真的 bool testB=方法是常量::值;//应该是假的 在
type\u traits
标题中,我找到了一个可以使用的
is\u const
测试,但我需要方法类型,我不确定如何获得它


我试过:
std::is_const::value
但它不起作用,我能理解为什么(
void(*ptr)()const)!=const void(*ptr)(
)。

检查成员函数是否可以在
const
限定左值上调用要简单得多

template<class T>
using const_lvalue_callable_foo_t = decltype(std::declval<const T&>().foo());

template<class T>
using has_const_lvalue_callable_foo = std::experimental::is_detected<const_lvalue_callable_foo_t, T>;

如果你想
const volatile
也成为
true
的话,那么沿着这条线去掉另外6个部分专门化。

std::is_const::value不起作用的原因是const成员函数不是const(成员函数)。它不是一个顶级的
const
,与
const int
vs
int
相比

我们可以做的是使用
void\u t
测试是否可以调用常量
t
上的
method
的类型特征:

template <typename... >
using void_t = void;

template <typename T, typename = void>
struct is_const_callable_method : std::false_type { };

template <typename T>
struct is_const_callable_method<T, void_t<
    decltype(std::declval<const T&>().method())
    > > : std::true_type { };
模板
使用void\u t=void;
模板
struct是_const_callable_方法:std::false_type{};
模板
结构是_const_callable_method>:std::true_type{};

在C++20中,事情变得容易多了,因为已经标准化了,包含了检测习惯用法

现在我们需要写的就是这个约束:

template<class T>
concept ConstCallableMethod = requires(const T& _instance) {
    { _instance.method() }
};

对于
A
ConstCallableMethod创建类型特征以确定方法的常量,约束将为
true

template<typename method_t>
struct is_const_method;

template<typename CClass, typename ReturnType, typename ...ArgType>
struct is_const_method< ReturnType (CClass::*)(ArgType...)>{
    static constexpr bool value = false;
};

template<typename CClass, typename ReturnType, typename ...ArgType>
struct is_const_method< ReturnType (CClass::*)(ArgType) const>{
    static constexpr bool value = true;
};
模板
结构是常量方法;
模板
结构是常量方法{
静态constexpr布尔值=真;
};

为了解决最后一部分,这是因为第一个是返回void的常量函数指针,第二个是返回const void的函数指针。另外,我想推测is_const捕获的是返回类型,而不是函数本身的const限定符。但是,我不能正确回答这个问题,因为我不确定该怎么做w使其按您所希望的方式运行。@William感谢您的帮助。是的,我不知道如何检查const限定符=/请原谅我的无知,但是您引用的链接是什么?它是否包含C++X标准中已经提供的官方扩展,或者是未来版本的建议?@JanitoVaqueiroFerreiraFilho这是一个有效的链接对于一个提议的技术规范,草案中的东西可能会进入下一个版本的C++标准。对于 iSuxDebug < /C>,它在两周前被投票,所以可能还没有实现,但是TS提供了一个完整的实现,所以你可以接受它并使用它。s函数只能在右值上调用,不是吗?@Columbo当然可以,但你真的在乎吗?我看不出
const&&
成员函数有什么好的用例。@t.C.Plus
volatile
,不是吗?
struct A {
    void method() const { }
};

struct B {
    void method() { }
};
template<class T>
concept ConstCallableMethodReturnsVoid = requires(const T& _instance) {
    { _instance.method() } -> void
};
template<class T, class MemberF>
concept ConstCallableMemberReturnsVoid = requires(const T& _instance, MemberF _member_function) {
    { (_instance.*_member_function)() } -> void
};
ConstCallableMemberReturnsVoid<A, decltype(&A::method)>
struct C
{
    void foobar() const{}
};
ConstCallableMemberReturnsVoid<C, decltype(&C::foobar)>
template<typename method_t>
struct is_const_method;

template<typename CClass, typename ReturnType, typename ...ArgType>
struct is_const_method< ReturnType (CClass::*)(ArgType...)>{
    static constexpr bool value = false;
};

template<typename CClass, typename ReturnType, typename ...ArgType>
struct is_const_method< ReturnType (CClass::*)(ArgType) const>{
    static constexpr bool value = true;
};