模板专门化的隐式实例化
Implicit instantiation of template specialization
我正在设计一个类模板Monad
,它由模板类型参数化。例如,可以有Monad<std::vector>
、Monad<std::shared_ptr>
等
我有这个实用程序struct
,它可以用来提取更高级类型的容器类型(例如,从std::vector<int>
中提取std::vector
):
template<typename>
struct FType;
template<typename A>
struct FType<std::vector<A>> {
template<typename B>
using type = std::vector<B>;
};
// FType<std::vector<int>>::type == std::vector
现在针对Monad
:
template<template <typename...> class F>
struct Monad;
template<>
struct Monad<std::vector> {
/*
* Example parameters:
* FA: std::vector<int>
* F: std::vector
* M: Monad<std::vector>
*/
template<typename FA,
template <typename...> class F = FType<FA>::template type,
typename M = Monad<F>>
static void foo(const FA &)
{
M::bark();
}
static void bark()
{
std::cout << "Woof!n";
}
};
我正在尝试让Monad::foo
自动推断其模板参数。因此,与其这么做:
std::vector<int> v{1, 2, 3};
// This works
Monad<std::vector>::foo<
std::vector<int>, // FA
std::vector, // F
Monad<std::vector> // M
>(v);
// This also works
Monad<std::vector>::foo<
std::vector<int>, // FA
std::vector // F
>(v);
我想能够做到:
std::vector<int> v{1, 2, 3};
// This does not compile
Monad<std::vector>::foo(v);
// Neither does this
Monad<std::vector>::foo<
std::vector<int> // FA
>(v);
我得到的错误(对于两个都没有编译的例子)是:
error: implicit instantiation of undefined template 'Monad<type>'
M::bark();
^
template is declared here
struct Monad;
^
error: incomplete definition of type 'Monad<type>'
M::bark();
~^~
我该如何解决这个问题?
更新:正如Sam所指出的,std::vector
、FType<std::vector<Something>>::type
和FType<std::vector<SomethingElse>>::type
都是不同的!(尽管对于特定的A
,std::is_same
表明std::vector<A>
、FType<std::vector<Something>>::type<A>
和FType<std::vector<SomethingElse>>::type<A>
是相同的。)如果我专门化Monad<FType<std::vector<int>>::type>
,那么事情就会解决。。。但显然这是不可取的。。。有其他方法可以实现FType
吗?
更新2:将FType
更改为:
template<typename... A>
struct FType<std::vector<A...>> {
template<typename... B>
using type = std::vector<B...>;
};
没有效果。
为什么它不起作用
问题是,当您显式地为F
提供std::vector
时,F
实际上就是std::vector
。但当你允许它被推导时,它被推导为FType<A>::type
——这是而不是std::vector
。这是可以推断的,但不一样。
如何修复
你实际上并没有。。。需要这些额外的机器来解决这个特殊的问题,对吗?您可以将参数推导为foo
作为模板模板的实例:
template <template <typename...> class F, typename... Args>
static void foo(F<Args...> const& ) {
using M = Monad<F>;
M::bark();
}
更一般地说,您可以在一个步骤中从FA
转到monad:
template <class FA>
struct as_monad;
template <class FA>
using as_monad_t = typename as_monad<FA>::type;
template <template <typename...> class F, typename... Args>
struct as_monad<F<Args...>> {
using type = Monad<F>;
};
然后:
template <class FA>
static void foo(FA const& ) {
using M = as_monad_t<FA>;
M::bark();
}
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 如何避免为模板化迭代器的每个可能的实例化专门化iterator_traits?
- 模板专门化的隐式实例化
- c++模板函数:显式实例化一个或多个专门化
- 专门化后的显式实例化
- 实例化后的显式专门化
- 即使具有显式实例化,也不会为显式专门化模板生成代码
- 如何防止非专门化模板实例化