gpt4 book ai didi

c++ - 模板的模板推导失败(中间有继承),有没有更好的方法?

转载 作者:搜寻专家 更新时间:2023-10-31 01:31:55 25 4
gpt4 key购买 nike

问题

我的代码中有以下方案,

#include <memory>
#include <iostream>

template <class T>
struct A {};

template <class T>
struct Z {};

template <class T, class U>
struct B : A<T>, Z<U> {};

template <class T>
struct C : B<T, T> {};

template <class T>
void foo(const std::shared_ptr<A<T>>& a)
{
std::cout << "HI !" << std::endl;
}

int main()
{
auto c = std::make_shared<C<char>>();

foo(c);

return 0;
}

但是编译器无法正确替换模板参数:

main.cpp: In function 'int main()':
main.cpp:26:10: error: no matching function for call to 'foo(std::shared_ptr<C<char> >&)'
foo(c);
^
main.cpp:17:6: note: candidate: template<class T> void foo(const std::shared_ptr<A<T> >&)
void foo(const std::shared_ptr<A<T>>& a)
^~~
main.cpp:17:6: note: template argument deduction/substitution failed:
main.cpp:26:10: note: mismatched types 'A<T>' and 'C<char>'
foo(c);
^

修复

所以我将 foo 更改为:

template <class T, template <class> class U>
void foo(const std::shared_ptr<U<T>>& a)
{
std::cout << "HI !" << std::endl;
}

更好的方法?

它可以工作,但感觉不对,因为现在对类型的模板约束非常松散,通常最终会产生更困惑的错误消息。

是否有更好的方法来处理此类模板推导失败?

在 Coliru 上玩这个例子

http://coliru.stacked-crooked.com/a/d4ebc14105c184df

最佳答案

有办法。您可以选择使用一些模板元编程手动约束模板,以便仅指针类型(可以扩展以使用各种指针类型,但仅适用于 unique_ptrshared_ptr 在这种情况下(实际上所有具有 element_type 类型别名的智能指针类型)都可以使用派生类。

#include <memory>
#include <iostream>

namespace {

/**
* Get the template type of a template template type
*/
template <typename T>
struct GetType;
template <typename T, template <typename...> class TT>
struct GetType<TT<T>> {
using type = T;
};
} // namespace <anonymous>

template <class T>
struct A {};

template <class T>
struct Z {};

template <class T, class U>
struct B : A<T>, Z<U> {};

template <class T>
struct C : B<T, T> {};

template <class T, typename std::enable_if_t<std::is_base_of<
A<typename GetType<typename std::decay_t<T>::element_type>::type>,
typename std::decay_t<T>::element_type>::value>* = nullptr>
void foo(const T&)
{
std::cout << "HI !" << std::endl;
}

int main()
{
auto c = std::make_shared<C<char>>();
auto c_uptr = std::make_unique<C<char>>();

foo(c);
foo(c_uptr);

return 0;
}

这现在可以与 unique_ptrshared_ptr 一起使用。您可以通过使用 decltype.get() 检查包含的指针类型(示例中的 element_type)来选择使其更通用在智能指针上,并创建一个特征来检测传递的指针是否是原始指针,如果是则只使用类型本身。但你明白了。

关于c++ - 模板的模板推导失败(中间有继承),有没有更好的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44615336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com