【问题标题】:decltype of template class without the template in C++C++中没有模板的模板类的decltype
【发布时间】:2018-07-17 12:01:09
【问题描述】:

我有一个模板函数template< template< class > class Timg, class T > Timg< T > foo() 的模板,编译器无法为其推断类型。我可以用foo< object, T >() 调用这个函数,其中object 是一个模板类。我希望能够使用decltype 或类似的方式调用此函数。

这里是一个例子:第一个文件是header.h

template< class T >
class object
{
};

template< template< class > class Timg, class T >
Timg< T > foo()
{
        return Timg< T >();
}

第二个文件是main.cpp

#include "header.h"

int main()
{
        object< float > o;
        auto l_return = foo< object, float >(); // OK
        auto l_return2 = foo< decltype(o), float >(); // What I would like to achieve
        return 0;
}

这里的问题是decltype(o) 返回object&lt; float &gt;,但我想只有object

如何从变量o 推断类型以将其作为函数foo 的模板参数传递?

【问题讨论】:

    标签: c++ class templates decltype type-deduction


    【解决方案1】:

    object 是类模板,而不是类型。只有类模板的实例才是类型。 object&lt;float&gt; 是一种类型。模板本身不是,它是模板……

    我不知道有什么方法可以直接推断出实例化类型的原始模板。您可以做的是定义一个帮助类模板并部分专门化以匹配参数类型是具有单个类型参数的模板实例的情况。这样,您可以推断给定object 实例的模板和参数类型。在这个帮助模板中,你可以有一个成员别名模板,它会再次给你一个 object 实例以及一个别名来转发参数类型

    template <class T>
    struct deduce_object_template;
    
    template <template <class> class O, class V>
    struct deduce_object_template<O<V>>
    {
        template <class T>
        using object_t = O<T>;
    
        using type = V;
    };
    

    然后使用它来调用foo,如下所示:

    foo<deduce_object_template<T>::template object_t, typename deduce_object_template<T>::type>();
    

    但是,我会严重质疑是否没有更简单的方法来实现您想要实现的目标。你真的需要推断模板和参数类型吗?如果你想要的只是创建一个类型参数的对象,为什么不简单地定义第二个模板

    template <class Timg>
    Timg foo()
    {
        return Timg();
    }
    

    并致电foo&lt;decltype(o)&gt;();?

    【讨论】:

    • 谢谢,这是一个聪明的解决方法!我举了一个简单的例子。我的函数看起来更像Timg&lt; Tout &gt; foo(Timg&lt; Tin&gt; x),这就是为什么我没有使用只有一个模板参数的第二个选项。
    • 在这种情况下,你能不能简单地从函数参数中推导出Timg,而不是明确指定参数:Timg&lt;bla&gt; foo(const Timg&lt;T&gt;&amp; in) {...}
    • 在您的示例中,它确实有效,因为T 是一种函数参数。在我的上下文中,T 在返回类型中,因此它更类似于template &lt;template &lt;class&gt; class Timg, class T&gt; Timg&lt;T&gt; foo(const Timg&lt;int&gt;&amp; in) {...},编译器无法推断。
    • 在这种情况下,只需将模板参数的顺序更改为template &lt;class T, template &lt;class&gt; class Timg&gt;。然后你可以写foo&lt;float&gt;(blub); 并从blub 推导出Timg 并且只显式指定返回类型的参数。
    • 确实如此,我想过。但是,按照模板参数出现的顺序编写模板参数更自然(它甚至可能在我公司的编码规则中),并且,对于这个问题,我预计我将在接下来的几天内编写更复杂的包装器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多