说,我有一些专门针对几种类型的模板,TypeMathcer
,其中有type
成员。
#include <memory>
#include <vector>
template <typename T>
struct TypeMatcher;
template <typename T>
struct TypeMatcher<T *>
{
// making some type from T
typedef std::shared_ptr<T> type;
};
template <typename T>
struct TypeMatcher<T&>
{
// making other type from T
typedef std::vector<T> type;
};
现在,我想创建另一个模板,并将其专门用于我从TypeMatcher
获得的类型。如果我直截了当,就像这样
template <typename T>
struct MyNeedfullTemplate;
template <typename T>
struct MyNeedfullTemplate<typename TypeMatcher<T>::type>
{
};
我收到编译错误:template parameters not deducible in partial specialization
。
如果使用using
语法
template <typename T>
using type_matcher_t = typename TypeMatcher<T>::type;
template <typename T>
struct MyNeedfullTemplate;
template <typename T>
struct MyNeedfullTemplate<type_matcher_t<T> >
{
};
我读到的问题partial specialization for iterator type of a specified container type的答案与我的问题非常相似,但仍然不确定是否存在一个反例让所有问题都变得毫无意义。现在我们还有全新的c ++ 14和c ++ 17标准,可以改变现状。那么,如果我确保专业化是独特的并且存在,那么比任何可能的参数都可以推导出来的那样呢?
答案 0 :(得分:2)
原则上这是不可能的,没有花哨的C ++ 9999可以改变它。
你要求编译器做什么:
代码中有MyNeedfulTemplate<int>
之类的用法。编译器需要MyNeedfulTemplate<U>
的{{1}}定义。您已尝试提供表单
U = int
要查看此专业化是否适用,编译器必须检查template <typename T>
struct MyNeedfullTemplate<typename TypeMatcher<T>::type>
所有可能的TypeMatcher<T>
s ,并查找其中是否有任何一个具有嵌套的typedef T
别名type
。这不可能发生,因为“所有可能int
s”的集合是无限的。好的,T
没有这样的类型,TypeMatcher<int>
,TypeMatcher<int*>
和TypeMatcher<int**>
也没有。但如果TypeMatcher<int***>
怎么办?最好继续尝试......
还要记住,存在部分和完整的专业化,这意味着TypeMatcher<int****>
本身可以是专门的。
简而言之,如果您拥有TypeMatcher
而不是int
,则没有方式可将TypeMatcher<X>::type
与int
相关联}。
你应该能够通过重新构造(反转)X
来实现类似的东西:
TypeMatcher
答案 1 :(得分:1)
我认为你要做的是:
#include <iostream>
#include <memory>
#include <vector>
#include <utility>
template <typename T>
struct TypeMatcher;
template <typename T>
struct TypeMatcher<T *>
{
// making some type from T
typedef std::shared_ptr<T> type;
};
template <typename T>
struct TypeMatcher<T&>
{
// making other type from T
typedef std::vector<T> type;
};
template <typename T, typename = void>
struct MyNeedfullTemplate;
template <typename T>
struct MyNeedfullTemplate<TypeMatcher<T>, std::enable_if_t<std::is_same<typename TypeMatcher<T>::type, std::vector<std::remove_reference_t<T>>>::value>>
{
static void report() { std::cout << "hello" << std::endl; }
};
int main()
{
using matcher_type = TypeMatcher<int&>;
using full_type = MyNeedfullTemplate<matcher_type>;
full_type::report();
return 0;
}
我能正确理解这个问题吗?