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

标签 c++ templates static macros

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

我特别想应用一个函数,如果对象具有该函数,它将输出对象的大小(即集合中对象的数量),但将输出一个简单的替换(例如“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/

相关文章:

c++ - 这段代码中如何发生内存泄漏

templates - 在 Word 2013 中添加自定义 "template group"

c++ - 类内部和外部的 static 关键字

C++ 删除静态数据

c++ - #include <winsqlite/winsqlite3.h> 在一个项目中工作,而不在另一个项目中工作

c++ - 将正态随机变量与任意 rho(corrcoef) 相关联

C++函数指针问题

c++ - 为什么 enable_if 不能在这里工作?

C# - 静态类型不能用作类型参数

c++ - 使用 strcpy 将 C++ 字符串转换为 Char 数组