是否可以编写c ++模板/宏来检查两个函数是否具有相同的签名

ser*_*eyz 4 c++ templates sfinae c-preprocessor

是否可以编写c ++模板/宏来检查两个函数是否具有相同的签名(返回类型和参数列表)?

这是一个我想如何使用它的简单示例:

int foo(const std::string& s) {...}
int bar(const std::string& s) {...}

if (SAME_SIGNATURES(foo, bar))
{
    // do something useful... make Qt signal-slot connection for example...
}
else
{
    // signatures mismatch.. report a problem or something...
}
Run Code Online (Sandbox Code Playgroud)

那么它有可能或者只是一个白日梦吗?

PS其实我对c ++ 2003标准感兴趣.

Naw*_*waz 17

C++ 11解决方案

无需自己编写任何模板.

您可以使用decltype连同std::is_same:

if (std::is_same<decltype(foo),decltype(bar)>::value )
{
    std::cout << "foo and bar has same signature" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这里decltype返回表达式的类型,在这种情况下是函数,并std::is_same比较两种类型,true如果两者都相同则返回,否则返回false.


C++ 03解决方案

在C++ 03中,您没有decltype,因此可以实现重载的函数模板:

template<typename T>
bool is_same(T,T) { return true; }

template<typename T, typename U>
bool is_same(T,U) { return false; }
Run Code Online (Sandbox Code Playgroud)

现在您可以将其用作:

if (is_same(foo, bar))
{
    std::cout << "foo and bar has same signature" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

现在,在这种情况下is_same是一个函数模板,而不是类模板.因此,它在运行时进行评估,而不是编译时.所以这会给出错误:

int a[is_same(foo,bar) ? 10 : 20]; //error (in Standard C++03)
                                   //the size must be known at compile-time!
Run Code Online (Sandbox Code Playgroud)

但是,如果您需要在编译时知道它,那么您需要更多地工作,并实现以下功能:

typedef char same[1];
typedef char different[2];

template<typename T>
same& is_same_helper(T,T);  //no need to define it now!

template<typename T, typename U>
different& is_same_helper(T,U); //no definition needed!

#define is_same(x,y)   (sizeof(is_same_helper(x,y)) == sizeof(same))
Run Code Online (Sandbox Code Playgroud)

现在用它作为:

if (is_same(foo, bar))
{
    std::cout << "foo and bar has same signature" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

您也可以在编译时使用它.所以你可以写它:

int a[is_same(foo,bar) ? 10 : 20]; //okay
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.