【问题标题】:C++11 templates and callback returns types with void specialization/overloadingC++11 模板和回调返回具有 void 特化/重载的类型
【发布时间】:2020-03-06 04:35:03
【问题描述】:

这是一个人为的例子,但它是重现我的问题的最少代码量。

这里我传递一个函数回调,结果被转换为字符串并推入向量。这适用于任何具有to_string 实现的类型。 (我使用函数指针而不是 std::function 因为一些函数来自第三方 C 库)

#include <vector>
#include <string>

template<typename R>
void Example(std::vector<std::string> &vec, R (*func)()) {
    auto r = func();
    vec.push_back(std::to_string(r));
}

int main(int argc, char **argv ) {
    std::vector<std::string> vec;

    Example(vec, static_cast<int(*)()>([]() -> int{
        return 0;
    }));

    Example(vec, static_cast<double(*)()>([]() -> double{
        return 0.0;
    }));
} 

然而,一种特殊情况是void。在这种情况下,我不希望将任何东西推送到向量。

// This obviously does not compile.
Example(vec, static_cast<void(*)()>([](){
    auto a = 0;
}));

我知道我可以重载Example,即

void Example(std::vector<std::string> &vec, void (*func)()) {
    func();
}

但在我的实际应用程序中,Example 要复杂得多,并且重载会导致大量复制粘贴代码。我尝试使用type_traits,但无法使用。

我还缺少另一种方法吗?

【问题讨论】:

  • 我标记 14 是因为我的真实世界代码将运行的最低版本。17 也适用于我。共享代码将很难提升。我不确定constexpr 在这里如何帮助我?能详细点吗?

标签: c++ templates c++14 c++17


【解决方案1】:

if constexpr 允许您有条件地编译代码,前提是条件取决于模板参数。对于 if constexpr#include&lt;type_traits&gt; 对于 std::is_same_v 类型特征,这需要 C++17。

template<typename R>
void Example(std::vector<std::string> &vec, R (*func)()) {
    if constexpr(std::is_same_v<R, void>) {
        func();
    } else {
        auto r = func();
        vec.push_back(std::to_string(r));
    }
}

【讨论】:

  • 谢谢。我确实做到了,但没有constexpr。我想我需要在17日学习!您的示例在 Mac 上对我不起作用,但 if constexpr(std::is_void&lt;R&gt;::value) 对我有用。再次感谢!
  • @szatmary 它们都应该在标准库中使用适当的 C++17 支持。如果它不尝试std::is_same&lt;R, void&gt;::value。 (虽然std::is_void&lt;R&gt; 在这里确实是一样的。)
  • 嗯。它现在正在工作(我一定有一个打字机)。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多