Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以检查函数是否具有无效返回类型_C++_C++11 - Fatal编程技术网

C++ 是否可以检查函数是否具有无效返回类型

C++ 是否可以检查函数是否具有无效返回类型,c++,c++11,C++,C++11,这个非常奇怪的请求出现了 我需要在编译时检查当前函数是否有void返回类型,如果返回类型为void,则编译失败 我也试着用anddecltype做一些魔术,但是我就是无法接近解决方案 #include <type_traits> void other_func(void) { } void test_maxi(void) { typedef decltype(&::other_func) TYPE; static_assert(std::is_same&l

这个非常奇怪的请求出现了

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

我也试着用and
decltype
做一些魔术,但是我就是无法接近解决方案

#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() {
}
#包括
无效其他函数(无效){}
最大无效测试(无效)
{
typedef decltype(&::other_func)类型;
静态断言(std::is_same::value,“notvoid”);
}
int main(){
}
所以问题来了:

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


编辑返回类型检查应在宏中进行,因为它将在多个函数中使用。

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

static_assert(!std::is_same<decltype(test_maxi()), void>::value, "void"); 
static_assert(!std::is_same::value,“void”);

如果一个字符串文字以另一个字符串文字开头,则可以实现编译时检查,并使用
\uuu PRETTY\u FUNCTION\uuuu
宏,该宏设置为以函数返回类型开头的字符串文字。您应该检查此宏是否以
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() {
}
如果将
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() {
}
static\u assert
将启动

>代码> Pr.TythyFix.Eng/<代码>宏似乎是特定于GNU C++编译器,但是,<代码> CLAN++//> >工作很好,因为它也定义了这个宏。如果您正在使用另一个编译器,您应该检查是否真的设置了此宏,如果没有,请阅读编译器文档以确定类似的设置 宏,例如,

\uuuu FUNCSIG\uuu


您可以使用
\ifdef\uu PRETTY\u FUNCTION\uuuu…
使其在各种编译器之间更易于移植,但我相信这是另一个问题的主题。

您只需检测返回类型并检查它是否为void类型。要检查类型,可以使用
std::is\u void
。可以使用以下模板检测返回类型:

#include <type_traits> // for is_void

template<typename R, typename... A>
void test(R (*func)(A...)) {
   static_assert(
       !std::is_void<R>::value, 
       "void return type is not allowed"
   ); 
}

// functions to check:
void a(int, char*) {}
int b(char, float) {return 0;}

int main()
{
    test(a); // < assert triggered here
    test(b);
}
\include//for is\u void
模板
无效试验(R(*func)(A…){
静态断言(
!std::is_void::value,
“不允许使用无效返回类型”
); 
}
//要检查的功能:
void a(int,char*){}
int b(字符,浮点){返回0;}
int main()
{
测试(a);//
您可以通过检查死
返回是否可以编译来检查当前函数的返回类型:

struct ConvertToAnything {
    template <class T>
    operator T() const { assert(!"Don't call me!"); }
};

#define CHECK_NONVOID_RETURN() if(true); else return ConvertToAnything{}

int f() {
    CHECK_NONVOID_RETURN(); // Passes
    return 42;
}

void g() {
    CHECK_NONVOID_RETURN(); // Fails at compile-time
}
struct ConvertToAnything{
模板
运算符T()常量{assert(!“不要叫我!”);}
};
#定义CHECK_nonoid_RETURN()如果为(true);否则返回ConvertToAnything{}
int f(){
检查_nonoid_RETURN();//通过
返回42;
}
void g(){
CHECK_nonoid_RETURN();//在编译时失败
}
void
的情况是一个特殊的情况,因此这就足够了。但也可以通过重载
ConvertToAnything::operator Type()=delete来禁止其他类型。允许
void
有点复杂,但仍然可行。

试试这个:

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

template <typename R, typename ... Args>
constexpr bool return_void(R(Args ...)) { return false; }
只要使用前六个函数调用,
return\u void
的所有调用都将返回true,
return\u void(l)
return\u void(m)
调用将返回false,因为它们将调用模板的第二个版本,即返回false的版本

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

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

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

    return 0;
}
intmain(){
静态断言(返回无效(f),“非无效”);
如果(!return_void(m))

std::cout Why?如果您试图将void赋值给任何对象,编译器都会对您大喊大叫。没有像当前函数这样的对象,那么如何获取类型?可能使用lambda而不是传统函数?让它作为另一个函数的模板参数的默认值并调用该函数?我想您会遇到与我知道(参见本例)这是一个小问题……我无法命名当前函数,这应该是一种宏类型的构造。@fritzone如果您可以将函数标记为
constexpr
,这将起作用。基于将其设为宏的奇怪要求(恶心)这是正确的答案。侧方注释:对于VisualC++,可以使用<代码>·y'SuffsiGuix。非常好。让我补充说,应该检查它是否以“空格”开头,以避免在返回代码< >空*>代码>或自定义结构>代码> VoIDFoO 的情况下开火。<代码>命名空间{Valuy(){\n#ifdef#u PRETTY#u FUNC#n#define BOB 1#else#define BOB 2#endif}
应该得到区分PRETTY FUNC或funcsig的
BOB
标记。通过一些游戏,应该能够定义一个
\u PRETTY#FUNC#u FUNC#的标记,如果它有效。。。
int main() {
    static_assert(return_void(f), "not void");

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

    return 0;
}