是否可以检查函数是否具有void返回类型

Fer*_*eak 10 c++ c++11

这个非常奇怪的要求出现了......

我需要做一个编译时检查当前函数是否有void返回类型,如果返回类型是,则编译失败void.

我试着做一些魔术http://en.cppreference.com/w/cpp/types/result_ofdecltype也,但是我不能更接近的解决方案.

#include <type_traits>

void other_func(void) { }

void test_maxi(void)
{
    typedef decltype(&::other_func) TYPE;
    static_assert(std::is_same<TYPE, void>::value, "not void"); 
}

int main() {
}
Run Code Online (Sandbox Code Playgroud)

所以这里有一个问题:

是否可以为当前功能执行此操作?

编辑返回类型检查应该在宏中,因为它将用于多个函数.

Ant*_*n K 14

如果一个字符串文字以另一个字符串开头,则可以实现编译时检查,并使用__PRETTY_FUNCTION__宏,该宏设置为以函数返回类型开头的字符串文字.你应该检查这个宏是否void以空格开头.

这段代码很好编译:

constexpr bool startsWith(const char* a, const char* b) {
    return *a == *b && (*(a + 1) == '\0' || startsWith(a + 1, b + 1));
}

int f() {
    static_assert(!startsWith("void ", __PRETTY_FUNCTION__), "not void");
    return 1;
}


int main() {
}
Run Code Online (Sandbox Code Playgroud)

如果将f返回类型更改为void:

constexpr bool startsWith(const char* a, const char* b) {
    return *a == *b && (*(a + 1) == '\0' || startsWith(a + 1, b + 1));
}

void f() {
    static_assert(!startsWith("void ", __PRETTY_FUNCTION__), "not void");
}


int main() {
}
Run Code Online (Sandbox Code Playgroud)

static_assert 会发射.

__PRETTY_FUNCTION__宏似乎是特定于GNU C++编译器,但是,clang++工作正常,因为它定义这个宏为好.如果您正在使用其他编译器,则应检查是否确实正在设置此宏,如果没有,请阅读编译器文档以确定类似的宏,例如__FUNCSIG__.

你可以#ifdef __PRETTY_FUNCTION__ ...在各种编译器之间使用它来使它更容易移植,但我相信这是另一个问题的主题.

  • 非常好.让我补充一点,你应该检查它以"void"开头,以避免触发返回`void*`或自定义struct`voidfoo`的方法. (3认同)

Mik*_*ine 5

如果您可以命名当前函数,那么最简单的方法是:

static_assert(!std::is_same<decltype(test_maxi()), void>::value, "void"); 
Run Code Online (Sandbox Code Playgroud)


Pap*_*ter 5

尝试这个:

template <typename ... Args>
constexpr bool return_void(void(Args ...)) { return true; }

template <typename R, typename ... Args>
constexpr bool return_void(R(Args ...)) { return false; }
Run Code Online (Sandbox Code Playgroud)

假设我们具有以下功能:

void f() {}
void g(int) {}
void h(int*,char&) {}
void i(float,bool) {}
void j(const char *const) {}
void k(void()) {}
int l() { return {}; }
float m(int) { return {}; }
Run Code Online (Sandbox Code Playgroud)

return_void只要对前六个函数进行调用,对to的所有调用都将返回true,而return_void(l)and return_void(m)调用将返回false,因为它们将调用模板的第二个版本,其中一个返回false。

Check it online

这将允许您检查函数是否void在运行时和编译时均返回:

int main() {
    static_assert(return_void(f), "not void");

    if (!return_void(m))
        std::cout << "m result is: " << m(0) << '\n';

    return 0;
}
Run Code Online (Sandbox Code Playgroud)