Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板专门化的隐式实例化_C++_Templates - Fatal编程技术网

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();
}