gpt4 book ai didi

c++ - 使 sfinae 适用于具有推导返回类型的函数?

转载 作者:搜寻专家 更新时间:2023-10-30 23:52:55 24 4
gpt4 key购买 nike

考虑以下代码:

// -------------------------------------------------------------------------- //
// Preprocessor
#include <array>
#include <vector>
#include <utility>
#include <iostream>
#include <type_traits>
// -------------------------------------------------------------------------- //



// -------------------------------------------------------------------------- //
// Calls a function without arguments if it can be called
template <
class F,
class... Args,
class = decltype(std::declval<F>()())
>
decltype(auto) apply(F&& f)
{
std::cout<<"apply(F&& f)"<<std::endl;
return std::forward<F>(f)();
}

// Calls a function with arguments if it can be called
template <
class F,
class Arg,
class... Args,
class = decltype(std::declval<F>()(
std::declval<Arg>(), std::declval<Args>()...
))
>
decltype(auto) apply(F&& f, Arg&& arg, Args&&... args)
{
std::cout<<"apply(F&& f, Arg&& arg, Args&&... args)"<<std::endl;
return std::forward<F>(f)(
std::forward<Arg>(arg),
std::forward<Args>(args)...
);
}

// Does nothing if the function cannot be called with the given arguments
template <
class F,
class... Args
>
void apply(F&& f, Args&&... args)
{
std::cout<<"apply(F&& f, Args&&... args)"<<std::endl;
}
// -------------------------------------------------------------------------- //



// -------------------------------------------------------------------------- //
// Main function
int main(int argc, char* argv[])
{
// Initialization
auto f = [](auto&& x) -> decltype(std::forward<decltype(x)>(x).capacity()) {
return std::forward<decltype(x)>(x).capacity();
};
auto g = [](auto&& x) -> decltype(auto) {
return std::forward<decltype(x)>(x).capacity();
};
auto h = [](auto&& x) {
return std::forward<decltype(x)>(x).capacity();
};

// Test
apply(f, std::vector<double>()); // -> sfinae works
apply(g, std::vector<double>()); // -> sfinae works
apply(h, std::vector<double>()); // -> sfinae works
apply(f, std::array<double, 1>());// -> sfinae works
//apply(g, std::array<double, 1>()); -> sfinae fails, does not compile
//apply(h, std::array<double, 1>()); -> sfinae fails, does not compile

// Return
return 0;
}
// -------------------------------------------------------------------------- //

实用程序apply,在可以编译时将函数应用于参数,否则什么也不做。该机制依赖于 sfinae。但是,对于返回类型是从主体推导的函数,如上例中的 gh,sfinae 失败。在 C++14 中是否有一种聪明的方法来修改 apply 实用程序,以便它强制 sfinae 启动,即使对于返回类型从主体推导的函数也是如此?

注意:我想让ghf一样工作,这意味着的调用应用 应该调用 void 版本。

最佳答案

SFINAE 只能捕获替换错误。

调用函数时的一些错误不能是替换错误。这些包括在您解析函数主体时发生的错误。

C++ 明确选择将这些错误排除在触发 SFINAE 之外,而是触发硬错误,以使编译器不必编译任意函数的主体以确定是否发生 SFINAE。由于 SFINAE 必须在重载解析期间完成,这使得 C++ 编译器的重载解析代码更容易。

如果您希望您的代码对 SFINAE 友好,则不能使用 gh 等 lambda。

关于c++ - 使 sfinae 适用于具有推导返回类型的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43034729/

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