Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;模板参数推断失败。为什么?_C++_Templates - Fatal编程技术网

C++ C++;模板参数推断失败。为什么?

C++ C++;模板参数推断失败。为什么?,c++,templates,C++,Templates,这将无法推断模板参数: Iter.h:272:27:注:忽略候选模板:模板参数推断失败[3] 为什么? 如果我使用指定的模板参数调用它,即getFilterInterator(worms(),&cForm::getLocal),它不会抱怨。我想知道为什么它不能像这样推断模板参数。我是否可以使它有所不同,以便它能够自动推断类型?您是说GetFilterIterator模板声明中第一个参数的类型是typname迭代器::Ref?如果是这样,则这不是模板类型参数的可推断上下文 考虑: template

这将无法推断模板参数:

Iter.h:272:27:注:忽略候选模板:模板参数推断失败[3]

为什么?


如果我使用指定的模板参数调用它,即
getFilterInterator(worms(),&cForm::getLocal)
,它不会抱怨。我想知道为什么它不能像这样推断模板参数。我是否可以使它有所不同,以便它能够自动推断类型?

您是说
GetFilterIterator
模板声明中第一个参数的类型是
typname迭代器::Ref
?如果是这样,则这不是模板类型参数的可推断上下文

考虑:

template<typename T> struct Ref {
     // ...
};

template<typename T> struct Iterator {
     // ...
};
模板
结构迭代器{
typedef int-Ref;
};
模板
结构迭代器{
typedef int-Ref;
};
getFiltererator(int(0),f);
Iterator::Ref
Iterator::Ref
都匹配传递给getFiltererator的参数,即一个int。它应该选择哪一个?C++不允许从你所声明的参数中推断模板类型。

随着问题的更新,您的意思似乎是
::Ref
。我认为这应该是可以推断的,因为typedef
迭代器::Ref
::Ref
它似乎应该能够推断
T
。我不确定它为什么不起作用。

编译器无法推断模板参数,因为拟合参数意味着一个不平凡的转换-首先到
迭代器,然后到
Ref
,两者都需要用户定义的转换。同样,直接将成员函数指针转换为boost::function对于编译器来说也是非常重要的

IBM有一个很好的解决方案

如果希望自动推导模板参数,则必须提供包装器方法:

template<>
struct Iterator<Foo> {
    typedef int Ref;
};
template<>
struct Iterator<Bar> {
    typedef int Ref;
};

GetFilterIterator(int(0),f);

<>这个代码在C++中更容易阅读,即使它可能不是一般的,它也不会使代码变得更糟。

由于XEO的提示,在推导模板参数时不允许隐式类型转换,所以我怀疑第二个参数会在这里引起问题。我认为它会从左到右进行类型推断,一旦类型被推断,就不再是问题了(对于指向
boost::function
cast的函数指针)

看来我错了,这正是问题所在

同一事物的另一个版本可以避免此问题:

for (auto it = worms().begin(); it != worms().end(); ++it)
  if (it->isLocal()) { 
    // Do something
  }
模板
结构PartialFuncWrapper{
::参考文献一;
PartialFuncWrapper(::Ref_i):i(_i){
typename迭代器::Ref运算符()(boost::函数pred){
返回新的过滤器(i,pred);
}
};
模板
PartialFuncWrapper GetFilterEditor(::Ref i){
返回PartialFuncWrapper(i);
}
然后我可以写:

template<typename T>
struct PartialFuncWrapper {
    ::Ref<Iterator<T> > i;
    PartialFuncWrapper(::Ref<Iterator<T> > _i) : i(_i) {}
    typename Iterator<T>::Ref operator()(boost::function<bool(T)> pred) {
        return new FilterIterator<T>(i, pred);      
    }
};

template<typename T>
PartialFuncWrapper<T> GetFilterIterator(::Ref<Iterator<T> > i) {
    return PartialFuncWrapper<T>(i);
}
Ref x=getFilterEditor(worms())(&cForm::getLocal);

什么类型是迭代器::Ref
boolcworm::getLocal()
无法匹配
boost::function
,因为它不带参数。作为成员函数,
getLocal
将充当
函数
@bames53:仅当它使用
std::mem\u fun
包装时。不涉及转换。它只需要将
Ref
Ref
匹配即可。我一直认为这不会是一个问题(我也不明白为什么会是这样;我很确定我在其他地方也看到过类似的东西)。而且,这已经决定了
T
,所以
boost::function
的东西就不再重要了。啊,你读过头了吗?“
worms()
返回一个
Ref
”。啊,很抱歉,错过了这一点。然后问题在于转换为boost::function——您将需要makeFn包装器或其他替代品。
for (auto it = worms().begin(); it != worms().end(); ++it)
  if (it->isLocal()) { 
    // Do something
  }
template<typename T>
struct PartialFuncWrapper {
    ::Ref<Iterator<T> > i;
    PartialFuncWrapper(::Ref<Iterator<T> > _i) : i(_i) {}
    typename Iterator<T>::Ref operator()(boost::function<bool(T)> pred) {
        return new FilterIterator<T>(i, pred);      
    }
};

template<typename T>
PartialFuncWrapper<T> GetFilterIterator(::Ref<Iterator<T> > i) {
    return PartialFuncWrapper<T>(i);
}
Ref<Iterator<CWorm*> > x = GetFilterIterator(worms())(&CWorm::getLocal);