gpt4 book ai didi

使用默认类型的 C++ 函数引用模板替换错误

转载 作者:行者123 更新时间:2023-11-28 05:28:44 31 4
gpt4 key购买 nike

考虑以下片段:

#include <type_traits>
#include <string>

template<typename T>
std::string stringify (const T& value)
{ return "dummy"; }

template<typename T>
class foo_class
{
public:
template<typename Converter = std::string(&)(const T&),
class = typename std::enable_if<std::is_convertible<
typename std::result_of<Converter(const T&)>::type,
std::string>
::value>::type>
foo_class(const T &value, const Converter &converter = stringify<T>) {}
};

int main(int,const char*[])
{
int X = 7;
foo_class<int> x(X);
foo_class<int> y(X, stringify<int>);
}

第一个构造函数编译得很好,但是第二个构造函数在 Clang 3.6.2 下失败并出现以下错误:

candidate template ignored: substitution failure [with Converter = std::__cxx11::basic_string<char> (const int &)]: function cannot return function type 'std::__cxx11::basic_string<char> (const int &)'
foo_class(const T &value, const Converter &converter = stringify<T>) {}

我深入研究并找到了一种修复它的方法,方法是将参数列表中的 const Converter & 更改为 Converter,尽管这可能不是期望的行为一些情况。

错误是由 std::enable_if<..> 子句中的某些内容引起的。我可以删除它,代码编译(和运行)就好了。

我主要对“为什么”这个问题感兴趣——为什么它在第一种情况下有效(当函数被选为默认参数时),但在第二种情况下,当它被明确选择时却不起作用。

作为次要问题,处理该问题的最佳方式是什么?我的意思是,我有一个解决方法,但我更愿意对非函数的参数坚持“默认情况下的 const 引用”策略。

最佳答案

这不是您应该使用的方式 result_of .

它应该始终与引用一起使用,其中引用的种类指定了您想知道其结果的调用中相应表达式的值类别。

所以如果你调用 converter作为 const左值,那么你会做 result_of<const Converter &(const T&)> .再举几个例子:

// forward the value category of the function object
template<class F>
auto f(F&& f) -> std::result_of_t<F&&()> { return std::forward<F>(f)(); }

// always call as an lvalue, accept both lvalue and rvalue function object
template<class F>
auto f(F&& f) -> std::result_of_t<F&()> { return f(); }

// Accept everything by value, but call with all lvalues
template<class F, class... Args>
auto f(F f, Args... args) -> std::result_of_t<F&(Args&...)> { return f(args...); }

// Accept everything by value, and move them all
template<class F, class... Args>
auto f(F f, Args... args) -> std::result_of_t<F&&(Args&&...)> { return std::move(f)(std::move(args)...); }

关于使用默认类型的 C++ 函数引用模板替换错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40004424/

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