我正在设计一个类模板
我有一个工具
我得到的错误信息(两个未编译的示例都是如此)为:
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...>;
};
没有任何效果。
-std=c++11 -Wall -Wextra -pedantic-errors
,g++ 4.8/4.9/5.3和Xcode 7.3附带的clang++都可以编译它(在OS X上)。也许您没有使用C++11? - Zizheng Taistd::vector
作为参数。这与Ftype... :: type的结果不匹配。我认为这样做行不通。 - Sam Varshavchikstd::vector
。对于不起作用的情况,您将 F 解析为基本上是template<typename B> class std::vector
。这两者并不相同。 - Sam VarshavchikFType
,但它仍然无法工作。请参见上面的更新。 - Zizheng Tai