当前位置: 首页 > 知识库问答 >
问题:

如何编写一个模板,可以推导类型使用函数的参数类型?

钱星华
2023-03-14
void foo(int *p) {}

template<typename T, void (*F)(T*)>
struct bar
{
    bar(T* t)
    {
        F(t);
    }
}

int *p;
bar<int, foo> b(p); // both int and foo are required here
bar<foo> b(p);

共有1个答案

邴姚石
2023-03-14

如果您可以将C++17与它的auto模板参数一起使用(就像@n.m.在注释中所说的那样),那么您可以将它用作模板参数,然后将类型T与类型traits一起使用。

首先,我们需要标准类型特征和一个类型特征来获得一元函数(您的foo)的参数,我们可以这样编写:

#include <type_traits>

// Trait to get the argument type of a unary function
template<typename T>
struct unary_func_arg;

template<typename R, typename T>
struct unary_func_arg< R(*)(T) >
{
    using type = T;
};

如果将函数指针以外的任何内容放入其中,这将产生一个错误,因为主专门化没有声明。

template< auto F >
struct bar
{
    // Assert it's a function pointer
    static_assert( std::is_pointer_v<decltype(F)> );
    static_assert( std::is_function_v< std::remove_pointer_t<decltype(F)> > );

    // Get the parameter type
    using T = typename unary_func_arg< decltype(F) >::type;

    bar(T t)
    {
        F(t);
    }
};
int* p;
bar<foo> b(p);
// Trait to get the argument type of a unary function
template<typename T>
struct unary_func_arg_pointer;

template<typename R, typename T>
struct unary_func_arg_pointer< R(*)(T*) >
{
    using type = T;
};
 类似资料:
  • 我发现了和类型推导的以下行为,这对我来说是意想不到的: 中的两行都会导致错误: 没有函数模板“stdfunc_test”的实例与参数列表匹配 尝试在Visual Studio 2015中编译时。 为什么类型演绎不从函数类型中演绎模板类型,有没有变通方法?

  • 使用以下代码生成时 生成以下诊断(代码后): 诊断: 有趣的部分不是关于歧义错误本身(这不是这里主要关注的问题)。有趣的是,当仅使用函数名调用fun时,第一个fun的模板参数F被解析为纯函数类型double(double),而第二个fun的模板参数F被解析为更期望的函数指针类型。 然而,当我们将调用<代码>乐趣(测试) 更改为<代码>乐趣( 这种行为似乎是所有Clang和GCC(以及Visual

  • 考虑以下示例: 而且,如果我们将非类型模板参数的类型改为占位符类型,如下所示: 然后,GCC接受,而Clang拒绝它(两者都拒绝,如上)。 海合会演示,铿锵演示。 (1)GCC HEAD 11.0.0 202 10117和Clang HEAD 12.0.0(20210118),。

  • 如果我没有理解错的话,类模板定义了一个函数,所以当我调用时,编译器有可能进行隐式强制转换,但是在函数模板的情况下,此时没有函数定义,所以隐式强制转换不会发生。 但我不明白为什么编译器不能创建函数定义,然后应用隐式强制转换? 错误是: 在函数“int main()”中:    25:24:错误:调用“test2::add(void(&)(int))”没有匹配函数    25:24:注:候选人是:  

  • 我有一个模板类和一个模板返回类型的函数: 假设我想为一个特定类型扩展返回的,并专门为该类型使用函数。因此,让我们创建一个模板来保存返回类型,并在中使用它: 并用它来提供专业化: 然而,gcc和clang都拒绝了最终声明。例如,clang返回: 错误:没有与函数模板专门化“build_wrapped”匹配的函数模板 注意:已忽略候选模板:无法推断模板参数“t” 通过为创建一个明确的专门化,我可以使用

  • 我正在尝试创建一个。我想直接使用它。e、 g.。但是,当从转换为