c++ - 仅当类有一个特定方法时如何调用?

标签 c++ templates c++14 template-meta-programming c++17

我有一个不同类对象的元组。我想遍历元组并仅在这些类有一个方法时才调用某个方法。

例如(伪代码):

struct A {  int get( ) { return 5; }; };
struct B { }; 
struct C {  int get( ) { return 10; }; };
int i = 0;
tuple<A, B, C> t;
for ( auto t_element : t ) 
{
    if constexpr ( has_get_method( decltype(t_element) ) )
    {
        i += t_element.get( );
    }
}

我已经知道如何遍历元组并使用 sfinae 检查类是否有某种方法,但如何跳过没有所需方法的对象?

编辑: 如果您以后发现这个老问题,请知道现在使用 C++20 标准中的概念可以更轻松地完成此问题。

最佳答案

只需编写一个 sfinae 函数和一个catchall 以防前一个失败。您不必为此使用 if constexpr 并且实际上不能在 C++14 中使用它(这就是您标记问题的方式)。
这是一个最小的工作示例:

#include <tuple>
#include <iostream>

auto value(...) { return 0; }

template <typename T>
auto value(T &t) -> decltype(t.get()) {
    return t.get();
}

struct A { int get() { return 5; }; };
struct B {}; 
struct C { int get() { return 10; }; };

int main() {
   int i = 0;

   std::tuple<A, B, C> t;

   i += value(std::get<0>(t));
   i += value(std::get<1>(t));
   i += value(std::get<2>(t));

   std::cout << i << std::endl;
}

wandbox 上查看它的启动和运行情况.

如果您想使用任何参数来测试它,您可以使用 std::forward 作为:

template <typename T, typename... Args>
auto value(T &t, Args&&... args)
-> decltype(t.get(std::forward<Args>(args)...))
{ return t.get(std::forward<Args>(args)...); }

然后调用它:

i += value(std::get<0>(t), params);

关于c++ - 仅当类有一个特定方法时如何调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46258407/

相关文章:

c# - 构建期间未转换的 T4 模板

c++ - 如何在 C++ 中显式调用异常抛出方法?

c++ - 在 Mac 上使用 C 或 C++ 进行 GUI 编程入门

c++ - Boehm 垃圾收集器中的精确模式

c++ - 了解模板偏特化

c++ - 使用非默认可构造类型填充 std::array(无可变参数模板)

c++ - 尝试获取矩阵的右对角线会导致 "vector out of range"错误

c++ - 使用存储在 vector 中的函数指针

c++ - 数组排序难度

c++ - 在模板编程方面需要一些帮助