我遇到了gcc 4.9.2
(使用-std=c++11)没有编译一段代码的问题,错误消息是
重载的‘InsertDataIntoInputMap(
&,boost::shared_ptr&)’的int调用不明确
代码可以使用msvc 2013进行编译
#include <iostream>
#include <map>
#include <boost/shared_ptr.hpp>
struct Proxy
{
typedef std::map<int, int> InputDataMap;
int a;
};
template<class C, class D>
void InsertDataIntoInputMap(
const typename C::InputDataMap::key_type& key,
const D val)
{
std::cout << "Not shared\n";
}
template<class C, class D>
void InsertDataIntoInputMap(
const typename C::InputDataMap::key_type& key,
const boost::shared_ptr<D> val)
{
if (val)
{
std::cout << "Shared\n";
}
}
int main() {
int a;
boost::shared_ptr<double> x(new double(4.5));
InsertDataIntoInputMap<Proxy>(a, x);
}
而下面的代码实际上是用gcc和msvc编译的:
#include <iostream>
#include <boost/shared_ptr.hpp>
template<class C, class D>
void InsertDataIntoInputMap(
const C& key,
const D val)
{
std::cout << "Not shared\n";
}
template<class C, class D>
void InsertDataIntoInputMap(
const C& key,
const boost::shared_ptr<D> val)
{
if (val)
{
std::cout << "Shared\n";
}
}
int main() {
int a = 0;
boost::shared_ptr<double> x(new double(4.5));
InsertDataIntoInputMap<int>(a, x);
return 0;
}
我认为编译器在这两种情况下都应该接受带有boost::shared_ptr参数的函数?
发布于 2015-08-08 05:05:06
这个问题可以归结为偏序中的不精确:在推导中没有出现模板参数的对仍然被考虑和比较。CWG #455和#885也解决了这个问题。
在您的示例中,重载解析无法区分重载。因此,偏序是必要的。偏序将尝试执行两次演绎,参数类型P
为typename C::InputDataMap::key_type
。
然而,这种推论注定要失败,因为C
只出现在非演绎的上下文中。即,来自两个模板的类型(对于该特定对)至少不像来自各自的另一个模板的类型那样专门化-这反过来意味着这两个模板中没有一个比另一个更专门化。
正如@T.C.所指出的,CWG #1391的分辨率是有帮助的。特别是这一部分:
更改14.8.2.4 temp.deduct.partial第4段如下:
上面从参数模板中指定的每个类型和参数模板中的相应类型都用作P
和A
的类型。如果特定的模板P
不包含参与模板实参推导的模板参数,则不使用该模板参数来确定排序。
现在,第一个参数对在两种情况下都被完全忽略了(因为C
的类型完全由显式参数列表确定),而第二个重载被发现更加专门化。
发布于 2015-08-06 21:21:52
一个简单的别名就可以让代码正常工作:
#include <iostream>
#include <map>
#include <boost/shared_ptr.hpp>
struct Proxy
{
typedef std::map<int, int> InputDataMap;
int a;
};
template<class C, class D, class F = typename C::InputDataMap::key_type>
void InsertDataIntoInputMap(
const F& key,
const D val)
{
std::cout << "Not shared\n";
}
template<class C, class D, class F = typename C::InputDataMap::key_type>
void InsertDataIntoInputMap(
const F& key,
const boost::shared_ptr<D> val)
{
if (val)
{
std::cout << "Shared\n";
}
}
int main() {
int a;
boost::shared_ptr<double> x(new double(4.5));
InsertDataIntoInputMap<Proxy>(a, x);
}
但是国际海事组织。这应该行不通,因为我认为,草案说,编译器不会考虑C::InputDataMap - Namespace在
class F = typename C::InputDataMap::key_type
而F将是一个非推导的上下文(如key_type)。
https://stackoverflow.com/questions/31563235
复制相似问题