C++ 如何传递模板非类型成员函数指针?

C++ 如何传递模板非类型成员函数指针?,c++,templates,template-templates,C++,Templates,Template Templates,我想将指向另一个模板成员函数的指针作为模板非类型参数传递给模板成员函数 以下是我尝试过的: enum Unit { model_unit, nanometers, meters }; struct Material { double rho; }; struct Point { double x, y, z; }; struct Impl{ template<Unit unit> Material * LookupMat_1(const Po

我想将指向另一个模板成员函数的指针作为模板非类型参数传递给模板成员函数

以下是我尝试过的:

enum Unit { model_unit, nanometers, meters };

struct Material {
     double rho;
};

struct Point {
    double x, y, z;
};

struct Impl{

    template<Unit unit>
    Material * LookupMat_1(const Point& p) {
        return nullptr; // let's suppose it returns a valid pointer
    }

    template<Unit unit>
    Material * LookupMat_2(const Point& p) {
        return nullptr; // let's suppose it returns a valid pointer
    }

    // compiler error here:
    // expected 'class' or 'typename' before 'Material'
    // template<template<Unit> Material * (Impl::*LookupFunc)(const Point&)
    //                         ^~~~~~~~
    template<template<Unit> Material * (Impl::*LookupFunc)(const Point&) >
    Material * GetMaterial(const Point & p) {

        return (this->*LookupFunc<Unit::model_unit>)(p);
    }

    void DoSomething() {

        Point p = {};

        auto mat_1 = GetMaterial<LookupMat_1>(p);
        auto mat_2 = GetMaterial<LookupMat_2>(p);
    }
};

int main() {

    Impl i;

    i.DoSomething();

}
enum单位{model_单位,纳米,米};
结构材料{
双rho;
};
结构点{
双x,y,z;
};
结构Impl{
模板
材料*LookupMat_1(施工点和工艺){
return nullptr;//假设它返回一个有效指针
}
模板
材料*LookupMat_2(施工点和工艺){
return nullptr;//假设它返回一个有效指针
}
//此处出现编译器错误:
//“物料”之前应为“类”或“类型名”
//模板*LookupFunc)(p);
}
无效剂量测定法(){
点p={};
自动材料1=获取材料(p);
自动材料2=获取材料(p);
}
};
int main(){
Impl i;
i、 DoSomething();
}
我的语法错误,编译器说:

main.cpp:25:29:错误:在“Material”之前应该是“class”或“typename”

模板正如注释中所解释的,模板函数(或方法)没有一个指针,因为它不是一个函数,而是一组函数

我所能想象的最好的类似操作(我的意思是……解释
Unit
内部的
GetMaterial()
)是使用静态模板方法在
Impl
中添加两个子结构

   struct lm1
    {
      template <Unit U>
      static Material * func (Point const & p)
       { return nullptr; }
    };

   struct lm2
    {
      template <Unit U>
      static Material * func (Point const & p)
       { return nullptr; }
    };
这样使用它

void DoSomething()
 {
   Point p = {};

   auto mat_1 = GetMaterial<lm1>(p);
   auto mat_2 = GetMaterial<lm2>(p);
 }

下面是类模板作为函子的方法

template<Unit unit>
struct LookupMat_1
{
   Material * operator()(const Point& p) {
       return nullptr;
   }
};

template<Unit unit>
struct LookupMat_2
{
   Material * operator()(const Point& p) {
       return nullptr;
   }
};

template<template<Unit> typename LookupMat>
Material * GetMaterial(const Point & p)
{
    return LookupMat<Unit::model_unit>()(p);
}
模板
结构查找表1
{
物料*运算符()(常数点和p){
返回空ptr;
}
};
模板
结构查找表2
{
物料*运算符()(常数点和p){
返回空ptr;
}
};
模板
材料*获取材料(施工点和工艺)
{
返回LookupMat()(p);
}

模板参数始终是类模板,而不是函数模板。语法始终是
模板类或typename
@n.m。因此,我应该能够使用模板类作为函子来执行此操作吗?没有指向模板的指针。不过,您可以使用指向特定模板实例化的指针。也许这可以推动您前进:而且:太好了,谢谢!为什么
return T::template func(p)中需要
template
?我从未见过这种情况。@ThreeStarProgrammer57-有时需要
template
来告诉编译器被调用的方法是
template
方法;坦白地说,我很难理解什么时候需要,什么时候不需要。这个案子似乎是必须的。是的,这正是我在读了你的评论后所做的。谢谢
void DoSomething()
 {
   Point p = {};

   auto mat_1 = GetMaterial<lm1>(p);
   auto mat_2 = GetMaterial<lm2>(p);
 }
enum Unit { model_unit, nanometers, meters };

struct Material
 { double rho; };

struct Point
 { double x, y, z; };

struct Impl
 {
   struct lm1
    {
      template <Unit U>
      static Material * func (Point const & p)
       { return nullptr; }
    };

   struct lm2
    {
      template <Unit U>
      static Material * func (Point const & p)
       { return nullptr; }
    };


   template <typename T>
   Material * GetMaterial (Point const & p)
    { return T::template func<Unit::model_unit>(p); }

   void DoSomething()
    {
      Point p = {};

      auto mat_1 = GetMaterial<lm1>(p);
      auto mat_2 = GetMaterial<lm2>(p);
    }
 };

int main ()
 {
   Impl i;

   i.DoSomething();
 }
template<Unit unit>
struct LookupMat_1
{
   Material * operator()(const Point& p) {
       return nullptr;
   }
};

template<Unit unit>
struct LookupMat_2
{
   Material * operator()(const Point& p) {
       return nullptr;
   }
};

template<template<Unit> typename LookupMat>
Material * GetMaterial(const Point & p)
{
    return LookupMat<Unit::model_unit>()(p);
}