2015-07-21 78 views
8

在我的代码中,我使用模板图像类Image<T>std::shared_ptr的组合。这些图像指针应该被传递给各种图像处理功能,其中一些独立于图像类型。考虑Image<T>的以下定义,以及两个处理函数function1()function2()相关类型:模板参数扣除失败

#include <memory> 

template <typename T> 
struct Image 
{ 
    typedef std::shared_ptr<Image<T>> Ptr; 
}; 

template <typename T> 
void function1 (typename Image<T>::Ptr image) {} 

template <typename T> 
void function2 (std::shared_ptr<Image<T>> image) {} 

虽然function1()function2()有效地具有相同的签名,function1()更容易阅读和隐藏的指针是如何实现的细节。但是,我无法在不明确指定模板类型的情况下调用function1()。请看下面的代码:

int main (void) 
{ 
    Image<int>::Ptr image = std::make_shared<Image<int>>(); 
    function1(image);  // Does NOT compile 
    function1<int>(image); // Does compile 
    function2(image);  // Does compile 
    return 0; 
} 

当第一次调用导致编译错误:

example.cc: In function 'int main()': 
example.cc:18:19: error: no matching function for call to 'function1(MyClass<int>::Ptr&)' 
example.cc:18:19: note: candidate is: 
example.cc:10:6: note: template<class T> void function1(typename MyClass<T>::Ptr) 
example.cc:10:6: note: template argument deduction/substitution failed: 
example.cc:18:19: note: couldn't deduce template parameter 'T' 

我的问题是:是否有可能使用的function1()签名,而无需手动指定模板参数?什么导致编译器错误?

我怀疑问题是由于Image<T>::Ptr是一个依赖类型。因此编译器在编译时无法知道该字段的确切定义。是否有可能告诉编译器这个字段没有专门化,typename关键字的精神告诉编译器一个字段是一个类型?

回答

7

What is causing the compiler error?

使用非推断上下文 T

你(只):嵌套名称 - 符秒。也就是说,你把T放在一个名字里面,这个名字只是指明类型在哪里。编译器无法理解你的实际意图,并且不得不尝试很多T's。

Is it possible to use the signature of function1() without having to manually specify the template argument?

不是。如果你想指的是智能指针到图像的更简洁的方式,你虽然可以使用别名模板:

template <typename T> 
using ImagePtr = std::shared_ptr<Image<T>>; 

而写function1正是如此:

template <typename U> 
void function1(ImagePtr<U> p) {} 
+0

通过“不是真的”,你意思是“不”对吧? – Barry

+0

@Barry那么,我还没有检查过,如果VC++中的疯狂错误使它在那里工作,但是 - 没有。 – Columbo