【问题标题】:std::make_pair, c++11 and explicit template parameters [duplicate]std::make_pair,c++11 和显式模板参数 [重复]
【发布时间】:2015-03-31 15:23:29
【问题描述】:

重新编辑:首先,这只是一个好奇的问题,我知道,std::pair 或许多其他解决方案可以根除这个问题。

你能告诉我,下面这个问题的背后究竟是什么吗?此代码是在 c++03 上运行的简单示例,在 c++11 上失败。

    std::pair<int*,int**> getsth(int* param)
    {
        return std::make_pair<int*,int**>(param, 0);
    }

    int main(int argc, char* argv[])
    {
        int* a = new int(1);
        std::pair<int*,int**> par = getsth(a);
        std::cout << *par.first;
        return 0;
    }

我确实知道如何修复它以兼容这里的两种标准,但它让我很恼火,我不知道在这种情况下 make_pair 背后究竟是什么。

谢谢!

已编辑:来自 Coliru 的编译错误消息:

main.cpp: In function 'std::pair<int*, int**> getsth(int*)':
main.cpp:8:47: error: no matching function for call to 'make_pair(int*&, int)'
     return std::make_pair<int*,int**>(param, 0);
                                               ^
main.cpp:8:47: note: candidate is:
In file included from /usr/local/include/c++/4.9.2/bits/stl_algobase.h:64:0,
                 from /usr/local/include/c++/4.9.2/bits/char_traits.h:39,
                 from /usr/local/include/c++/4.9.2/ios:40,
                 from /usr/local/include/c++/4.9.2/ostream:38,
                 from /usr/local/include/c++/4.9.2/iostream:39,
                 from main.cpp:1:
/usr/local/include/c++/4.9.2/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
     make_pair(_T1&& __x, _T2&& __y)
     ^
/usr/local/include/c++/4.9.2/bits/stl_pair.h:276:5: note:   template argument deduction/substitution failed:
main.cpp:8:47: note:   cannot convert 'param' (type 'int*') to type 'int*&&'
     return std::make_pair<int*,int**>(param, 0);
                                               ^
main.cpp:9:1: warning: control reaches end of non-void function [-Wreturn-type]
 }

【问题讨论】:

  • 请显示你的编译错误,假设有一个
  • std::make_pair&lt;int*,int**&gt;(param, 0)totally pointlessmake_pair的全部意义在于推导参数类型。如果您不想推断类型,那么只需说 std::pair&lt;int*,int**&gt;(param, 0) 并省去输入五个冗余字符。
  • 只是要指出return {param, 0};
  • @chris 03 年不上班。

标签: c++ c++11 c++03


【解决方案1】:

发生了右值引用。 C++03中std::make_pair的签名在哪里

template< class T1, class T2 >
std::pair<T1,T2> make_pair( T1 t, T2 u );

在 C++11 中,它有

template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );

V1V2(通常)是std::decay&lt;T1|T2&gt;::type。 C++14 添加了constexpr,但这确实与我们有关。

这意味着显式函数模板特化 std::make_pair&lt;int*, int**&gt; 在 C++03 中接受 int*int** 类型的参数,而 C++11 中的新函数模板特化接受 int*&amp;&amp;int**&amp;&amp; .

0 绑定到int**&amp;&amp; 没有问题,但param 是一个左值,不能绑定到对int* 的右值引用。这就是为什么您的代码在 C++11 中爆炸式增长的原因。

因此,

return std::make_pair<int*&, int**>(param, 0);

适用于 C++03 和 C++11 -- param 可以绑定到 int*&amp;,并且生成的 std::pair&lt;int*&amp;, int**&gt; 可以转换为函数想要在两者中返回的 std::pair&lt;int*, int**&gt;修订。

不过,这相当难看,std::make_pair 并不是真的要以这种方式使用。作为@T.C.在 cmets 中指出,如果您知道 std::pair 应该具有的类型,请使用

return std::pair<int*, int**>(param, 0);

【讨论】:

  • std::pair&lt;int*, int**&gt;(param, 0)make_pair 永远不会与显式模板参数一起使用。
  • 谢谢,这是我的猜测。但是它没有一个普通的 定义吗?
  • @newhouse 我认为他的意思是答案应该提到这一点,我同意 - 一年后它仍然会在这里,而且不仅仅是我们可能会阅读它。
  • @newhouse,你为什么认为 T.C.是个聪明人吗?为什么你认为return std::pair&lt;int*, int**&gt;(param, 0) 与返回类型不兼容?
  • @JonathanWakely 我看错了,是的,没关系。
【解决方案2】:

你需要去掉make_pair的模板参数。 Here 是关于原因的更多信息。

另外,您应该将nullptr 传递给make_pair,而不是0。

【讨论】:

  • 我认为问题在于它还需要符合 C++03 标准,我不知道是否可以,没有显式参数。
  • 您错过了“C++03 编译器”部分,以及我有一个确切的返回类型的事实,所以如果我删除 make_pair 的模板参数定义,它将无法编译要么。
  • @newhouse 如果您不使用 0 作为指针,它会。 C++03 中没有nullptr,但你仍然可以硬输入reinterpret_cast&lt;int**&gt;(0)
  • @GiulioFranco s/reinterpret/static/.
  • @GiulioFranco static_cast 保证工作。 reinterpret_cast 不是。
猜你喜欢
  • 2015-12-03
  • 2012-03-27
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多