依赖类型:模板参数推导失败[重复]

问题描述 投票:0回答:1

在我的代码中,我使用模板化图像类

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
关键字告诉编译器字段是类型的精神?

c++ templates c++11 type-inference
1个回答
8
投票

什么原因导致编译器错误?

您(单独)在非推导上下文中使用

T
嵌套名称说明符。也就是说,您将
T
放入仅指定类型所在位置的名称中。编译器无法理解你的实际意图,必须尝试很多
T

是否可以使用

function1()
的签名而无需手动指定模板参数?

其实不然。如果您想要一种更简洁的方式来引用图像的智能指针,您可以使用别名模板:

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

并这样写

function1

template <typename U>
void function1(ImagePtr<U> p) {}
© www.soinside.com 2019 - 2024. All rights reserved.