【问题标题】:Detecting void method in c++ template metaprogramming在 C++ 模板元编程中检测 void 方法
【发布时间】:2017-03-15 12:38:02
【问题描述】:

我正在尝试编写一个模板元函数来检测一个类型是否具有 void 类型的成员函数。

目前我可以使用 SFINAE 来检测成员函数是否具有明确的类型,例如 double、int 等。使用类似

 template<typename C> static auto Test(void*) -> decltype(int{std::declval<C>().foo()}, Yes{});

当然,我可以将其反转(如附加代码 sn-p 所示)以测试它不是 int,但我无法弄清楚如何测试它是否为 void。

下面的代码sn-p当前输出

A  does not have void foo
B  has void foo
C  has void foo

但是,C 的 foo() 方法具有 double 类型,因此这是不正确的输出。如何调整它以正确检查 void foo()

#include <iostream>
#include <memory>

class A {
public:
    int foo() {
        return 0;
    }
};

class B {
public:
    void foo() {
    }
};

class C {
public:
    double foo() {
        return 0;
    }
};

template <typename T>
class has_void_foo {
private:
  typedef char Yes;
  typedef Yes No[2];

  template<typename C> static auto Test(void*) -> decltype(int{std::declval<C>().foo()}, Yes{});
  template<typename> static No& Test(...);

public:
    static bool const value = sizeof(Test<T>(0)) != sizeof(Yes);
};

int main(void) {
    std::cout << "A ";
    if (has_void_foo<A>::value) {
        std::cout << " has void foo";
    } else {
        std::cout << " does not have void foo";
    }
    std::cout << std::endl << "B ";
    if (has_void_foo<B>::value) {
        std::cout << " has void foo";
    } else {
        std::cout << " does not have void foo";
    }
    std::cout << std::endl << "C ";
    if (has_void_foo<C>::value) {
        std::cout << " has void foo";
    } else {
        std::cout << " does not have void foo";
    }
    std::cout << std::endl;

    return 0;
}

【问题讨论】:

  • 你知道 C++11 中 &lt;type_traits&gt; 中的 std::is_void 吗?

标签: c++ template-meta-programming


【解决方案1】:

它遵循基于constexpr 函数的可能解决方案:

#include <type_traits>

struct A {
    int foo() {
        return 0;
    }
};

struct B {
    void foo() {
    }
};

struct C {
    double foo() {
        return 0;
    }
};

template<typename T, typename R, typename... Args>
constexpr bool has_void_foo(R(T::*)(Args...)) { return std::is_void<R>::value; }

int main() {
    static_assert(not has_void_foo(&A::foo), "!");
    static_assert(has_void_foo(&B::foo), "!");
    static_assert(not has_void_foo(&C::foo), "!");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多