假设有一个库,其中一个版本定义了名为$(document).ready(function() {
$('#promotedlinksbody_WPQ2').removeClass('ms-promlink-body');
$('#promotedlinksbody_WPQ2').addClass('row container-fluid');
$('#promotedlinksbody_WPQ2').children().removeClass('ms-tileview-tile-root');
$('#promotedlinksbody_WPQ2').children().addClass('col-md-4');
});
的函数,另一个版本的名称更改为foo
,但这两个函数仍具有相同的参数和返回值。我目前使用这样的条件编译:
foo_other
但这需要对库版本进行一些外部检测,并设置相应的编译器选项,如#include <foo.h>
#ifdef USE_NEW_FOO
#define trueFoo foo_other
#else
#define trueFoo foo
#endif
。我宁愿让代码自动确定它应该调用哪个函数,基于它是否在-DUSE_NEW_FOO
中声明。
有没有办法在任何版本的C中实现这一点?
如果没有,切换到任何版本的C ++会为我提供任何方法吗? (假设库在其标题中执行了所有必需的操作,例如<foo.h>
块)?也就是说,我正在考虑以某种方式利用SFINAE,但是对于全局函数而不是方法,这在链接问题中进行了讨论。
答案 0 :(得分:4)
在C ++中,你可以使用表达式SFINAE:
//this template only enabled if foo is declared with the right args
template <typename... Args>
auto trueFoo (Args&&... args) -> decltype(foo(std::forward<Args>(args)...))
{
return foo(std::forward<Args>(args)...);
}
//ditto for fooOther
template <typename... Args>
auto trueFoo (Args&&... args) -> decltype(fooOther(std::forward<Args>(args)...))
{
return fooOther(std::forward<Args>(args)...);
}
答案 1 :(得分:0)
如果你静态地链接到一个函数,在大多数C ++版本中,函数的名称是&#34; mangled&#34;反映其论点清单。因此,尝试通过具有过期.hpp
文件的程序静态链接到库将导致&#34;未知符号&#34;接头 - 错误。
在C语言中,没有任何类型的元数据表明任何导出函数实际的参数列表是什么。
实际上,我认为,您只需确定您用来链接到库的.h
或.hpp
个文件,实际上反映了您正在使用的库的任何版本中的相应对象代码。您还需要确保Makefile
(或&#34; auto-make&#34;进程)将正确识别应用程序中链接到该库的所有模块,因此必须是在任何更改的情况下重新编译。 (如果是我,我会重新编译整个应用程序。)简而言之,你必须确保此问题不会发生。
答案 2 :(得分:0)
在C ++中你可以这样做:
#include <iostream>
#include <type_traits>
//#define DEFINE_F
#ifdef DEFINE_F
void f()
{
}
#endif
namespace
{
constexpr struct special
{
std::false_type operator()() const;
}f;
}
struct checkForF
{
static const constexpr auto value = std::conditional< std::is_same<std::false_type, decltype(::f())>::value, std::false_type, std::true_type >::type();
};
int main()
{
std::cout << checkForF::value << std::endl;
}
请注意我只处理没有任何参数的f。