C++ 模板专门化的隐式实例化
我正在设计一个类模板C++ 模板专门化的隐式实例化,c++,templates,C++,Templates,我正在设计一个类模板Monad,它由模板类型参数化。例如,可以有Monad,Monad,等等 我有一个实用工具struct,可用于提取更高类型的容器类型(例如,从std::vector中提取std::vector): 我试图让Monad::foo自动推断其模板参数。因此,不要这样做: std::vector<int> v{1, 2, 3}; // This works Monad<std::vector>::foo< std::vector<int&
Monad
,它由模板类型参数化。例如,可以有Monad
,Monad
,等等
我有一个实用工具struct
,可用于提取更高类型的容器类型(例如,从std::vector
中提取std::vector
):
我试图让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);
没有效果。为什么不起作用
问题是,当您为F
显式提供std::vector
时,F
实际上是std::vector
。但当您允许它被推导时,它将被推导为FType::type
——这不是std::vector
。这是可以推断的,但它是不一样的
如何修复它
你实际上不。。。这个问题需要额外的机器吗?您可以将foo
的参数推断为模板的实例:
template <template <typename...> class F, typename... Args>
static void foo(F<Args...> const& ) {
using M = Monad<F>;
M::bark();
}
然后:
template <class FA>
static void foo(FA const& ) {
using M = as_monad_t<FA>;
M::bark();
}
模板
静态void foo(FA const&){
使用M=as_monad_t;
树皮();
}
this works部分对gcc不起作用:“模板参数推导/替换失败:t.C:48:6:注意:无法将'v'(类型'std::vector')转换为'std::vector&'——所以你已经在8球后面,从大门出来了。@SamVarshavchik我正在使用-std=C++11-Wall-Wextra-pedantic errors
,Xcode 7.3附带的g++4.8/4.9/5.3和clang++都可以编译它(在OSX上)。也许你没有使用C++11?如果你的评论是针对我的,我使用的是C++11模式下的gcc 5.3.1。新版本的GCC在执行C++时要严格得多。另外:Monad专门化将std::vector
作为参数。这与Ftype…::type产生的结果不匹配。我认为这行不通。为了使“this works”版本能够编译,我必须将std::move(v)作为参数传递给foo。这是有道理的。@SamVarshavchik啊,我明白了,那实际上是一个打字错误,很抱歉!我会更正foo的签名。关于您的附加注释,Ftype::type
本身不是完整类型,它也是模板类型。为什么它不起作用?实际问题更复杂。基本上,我有一个类型F
(std::vector
),一个可调用的类型Fn
,而std::result\u of::type
给出了一个G
(我作为一个整体返回,GB
)。问题是我无法将G
与GB
分开;我需要G
来找到专门的Monad
实现。@ZizhengTai只需通过类型跟踪一步就可以了谢谢!这正是我想要的!
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();
~^~
template<typename... A>
struct FType<std::vector<A...>> {
template<typename... B>
using type = std::vector<B...>;
};
template <template <typename...> class F, typename... Args>
static void foo(F<Args...> const& ) {
using M = Monad<F>;
M::bark();
}
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();
}