gpt4 book ai didi

c++ - 在编译时检测 C++ 中的函数

转载 作者:可可西里 更新时间:2023-11-01 18:41:23 26 4
gpt4 key购买 nike

有没有一种方法,大概是使用模板、宏或两者的组合,我可以将一个函数一般地应用于不同类的对象,但如果它们没有特定的函数,它们会以不同的方式响应?

我特别想应用一个函数,如果对象具有该函数,它将输出对象的大小(即集合中对象的数量),但将输出一个简单的替换(例如“N/A”)如果对象没有。即

NO_OF_ELEMENTS( mySTLMap ) -----> [ calls mySTLMap.size() to give ] ------>  10
NO_OF_ELEMENTS( myNoSizeObj ) --> [ applies compile time logic to give ] -> "N/A"

我希望这可能类似于静态断言,尽管我显然希望编译不同的代码路径而不是在构建阶段失败。

最佳答案

据我了解,您想进行通用测试以查看某个类是否具有某个成员函数。这可以在 C++ 中使用 SFINAE 完成.在 C++11 中它非常简单,因为你可以使用 decltype :

template <typename T>
struct has_size {
private:
template <typename U>
static decltype(std::declval<U>().size(), void(), std::true_type()) test(int);
template <typename>
static std::false_type test(...);
public:
typedef decltype(test<T>(0)) type;
enum { value = type::value };
};

如果您使用 C++03,由于缺少 decltype 会有点困难,所以你不得不滥用sizeof相反:

template <typename T>
struct has_size {
private:
struct yes { int x; };
struct no {yes x[4]; };
template <typename U>
static typename boost::enable_if_c<sizeof(static_cast<U*>(0)->size(), void(), int()) == sizeof(int), yes>::type test(int);
template <typename>
static no test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(yes) };
};

当然这使用了Boost.Enable_If ,这可能是不需要的(和不必要的)依赖项。然而写enable_if你自己很简单:

template<bool Cond, typename T> enable_if;
template<typename T> enable_if<true, T> { typedef T type; };

在这两种情况下,方法签名 test<U>(int)仅在 U 时可见有一个 size方法,因为否则评估 decltypesizeof (取决于您使用的版本)将失败,然后将从考虑中删除该方法(由于 SFINAE 。冗长的表达式 std::declval<U>().size(), void(), std::true_type() 是对 C++ 逗号运算符的滥用,它将返回逗号中的最后一个表达式-分隔列表,因此这确保类型被称为 std::true_type 对于 C++11 变体(sizeof 评估 int 对于 C++03 变体)。中间的 void() 只是那里确保逗号运算符没有奇怪的重载干扰评估。

当然,如果 T,这将返回 true有一个 size可以在没有参数的情况下调用的方法,但不保证返回值。我假设您可能只想检测那些不返回 void 的方法。这可以通过稍微修改 test(int) 轻松完成。方法:

// C++11
template <typename U>
static typename std::enable_if<!is_void<decltype(std::declval<U>().size())>::value, std::true_type>::type test(int);
//C++03
template <typename U>
static typename std::enable_if<boost::enable_if_c<sizeof(static_cast<U*>(0)->size()) != sizeof(void()), yes>::type test(int);

关于c++ - 在编译时检测 C++ 中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8911897/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com