gpt4 book ai didi

c++ - 为什么 std::result_of 将(不相关的)函数类型作为类型参数?

转载 作者:IT老高 更新时间:2023-10-28 22:01:27 25 4
gpt4 key购买 nike

我意识到“为什么会这样”的问题通常不是最好的问题,但是 SO 上有很多人关注标准委员会的讨论,所以我希望可以如实回答,因为我很好奇至于答案是什么。

基本上,当我第一次看到 std::result_of 的模板签名时,我花了很长时间才弄清楚它发生了什么:我认为这是一个全新的构造我以前从未见过的模板参数。

template< class F, class... ArgTypes >
class result_of<F(ArgTypes...)>;

经过一段时间的思考,我意识到这实际上是什么:F(ArgTypes...)是一个函数类型,但它不是的类型正在评估其结果类型的函数(这只是 F):它是采用 ArgTypes... 参数和 returning 类型的函数的类型 F.

这不是……奇怪吗?有点骇人听闻?有谁知道委员会是否曾经讨论过任何替代方案,例如,以下...

template< class F, class... ArgTypes >
class result_of<F, ArgTypes...>;

?

我想可能存在第二个构造不像第一个那样容易使用的情况,但是哪些情况呢?

我不是想对此做出判断,只是我第一次看到它时确实让我感到困惑,所以我很好奇这是否有充分的理由。我意识到部分答案可能只是“因为 Boost 做到了”,但仍然留下了剩下的(事实)问题......

  • Boost 选择这种语法来编码类型信息是否有技术原因而不是任何替代方法?

  • 考虑到 std::result_of 可以根据 decltype 还是相当容易?

最佳答案

将函数类型作为参数允许您拥有不受限制的“可变参数”类模板,即使在 C++03 中也是如此。想想看:在 C++03 中,我们没有可变参数模板。而且您不能像使用函数模板那样“重载”类模板 - 那么如何允许函数使用不同数量的“参数”?

使用函数类型,您可以为不同数量的参数添加任意数量的偏特化:

template<class Fty>
struct result_of;

template<class F>
struct result_of<F()>{ /*...*/ };

template<class F, class A0>
struct result_of<F(A0)>{ /*...*/ };

template<class F, class A0, class A1>
struct result_of<F(A0, A1)>{ /*...*/ };

// ...

在 C++03 中执行此操作的唯一其他方法是默认模板参数,并针对每种情况进行部分专门化 - 缺点是它看起来不再像函数调用,并且任何使用 result_of 内部不能只传递 Sig


现在,函数类型的方式有一个缺点 - 您还可以对“参数”进行所有常见的转换:R(Args...) -> R( *)(Args...) 更重要的是 T[N] -> T* 和顶级 cv 限定符被丢弃( §8.3.5/5):

struct X{
bool operator()(int (&&arr)[3]);
long operator()(void*);
};

static_assert(std::is_same<std::result_of<X(int[3])>::type, bool>(), "/cry");

Live example.输出:

error: static assertion failed: /cry

另一个问题是顶级 cv 限定符被丢弃:

struct Y{};

struct X{
bool operator()(Y const&);
long operator()(Y&&);
};

Y const f();

static_assert(std::is_same<std::result_of<X(Y const)>::type, bool>(), "/cry");

Live example.输出:

error: static assertion failed: /cry

关于c++ - 为什么 std::result_of 将(不相关的)函数类型作为类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15486951/

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