C++ C++;函数模板内的函数指针名称查找

C++ C++;函数模板内的函数指针名称查找,c++,c++11,argument-dependent-lookup,name-lookup,c++17,c++14,C++,C++11,Argument Dependent Lookup,Name Lookup,C++17,C++14,我试图理解名称查找和参数依赖项查找。我创建了一个小示例 编辑: #包括 void g(常数int*){} 模板 结构类型解析; 模板 结构类型解析{ typedef const T*type; 静态constexpr void(*func_ptr)(类型解析::类型)=g; 静态constexpr void*func_ptr_void=(void*)func_ptr; }; 模板 结构类型解析{ typedef const T*type; 静态constexpr void(*func_ptr)

我试图理解名称查找和参数依赖项查找。我创建了一个小示例

编辑:

#包括
void g(常数int*){}
模板
结构类型解析;
模板
结构类型解析{
typedef const T*type;
静态constexpr void(*func_ptr)(类型解析::类型)=g;
静态constexpr void*func_ptr_void=(void*)func_ptr;
};
模板
结构类型解析{
typedef const T*type;
静态constexpr void(*func_ptr)(类型解析::类型)=g;
静态constexpr void*func_ptr_void=(void*)func_ptr;
};
void foo_impl(void*[],void*[]){
//这里的一些工作,将在不同的文件或库中
}
模板
void foo(ARGS&&…ARGS){
void*func_ptrs[]={TypeResolution::func_ptr_void…};
void*args_ptrs[]={(void*)&args…};
foo_impl(函数、参数);
}
结构MyClass{};
void g(const MyClass*){}
int main(int argc,char*argv[]){
int i=1;
富(i),;
int j=2;
foo(i,j);
MyClass c;
foo(c);//这失败了。
}
所以我的问题是,为什么它不编译?或者更简单地说,为什么在声明类时,而不是实例化类时,会在TypeResolution中查找g?正如我在主函数中所期望的,然后看到函数
void g(const MyClass*)

我想要得到的是能够为不同的类型调用不同的函数,但不需要向前声明它们


我在Ubuntu16.04上使用了g++5.4.0,这是基于Yakk的回答和我设法实现了一个用c++14编译的解决方案

template <typename T>
void foo(T t) {
   void(*f)(T) = +[](T x){ return g(std::forward<T>(x)); };
   f(t); //This compiles
   g(t); //This compiles
}

#包括
#包括
#包括
void g(int*){}
模板
结构类型解析;
模板
结构类型解析{
结构内部{
静态constexpr void foo(T*T){g(T);}
};
静态constexpr void*func_ptr_void=(void*)内部::foo;
};
模板
结构类型解析{
结构内部{
静态constexpr void foo(T*T){g(T);}
};
静态constexpr void*func_ptr_void=(void*)内部::foo;
};
void foo_impl(void*函数参数[],void*数据参数[]){
//这里的一些工作,将在不同的文件或库中
}
模板
void foo(ARGS&&…ARGS){
void*func_ptrs[]={TypeResolution::func_ptr_void…};
void*args_ptrs[]={(void*)&args…};
foo_impl(函数、参数);
}
结构MyClass{};
void g(const MyClass*){}
int main(int argc,char*argv[]){
int i=1;
富(i),;
MyClass c;
傅(丙),;
}

你的意思是说
&g
编译不对?没有代码> G <代码>。你的代码为我编译,VS 2017(155.1),VC19.12,甚至没有C++标准集。<代码> GyLea/<代码>取决于<代码> T <代码> -但是我不确定这是如何相关的;您的问题不是查找
g_call
,而是查找
g
。当它出现在函数调用中时,它会被查找两次——在定义点进行普通查找,在实例化点进行ADL(是后者找到了它)。当它出现在
&g
中时,它不是一个从属名称,在定义时只被查找一次。@SoronelHaetir它之所以有效,是因为众所周知,MSVC没有实现两阶段查找,并将所有查找延迟到实例化点。只要没有实际使用
f
,它就可以愉快地编译
template void f(){random garbage here;}
。()您要求的是一种解决方法,但您没有描述您想要的。您只是在显示未编译的代码。我可以使您的编译以有限的方式进行,但没有任何线索表明您试图解决的根本问题是什么,我不知道哪个子集对您有用(如果有的话),因此有一个有限的post长度限制。@horatiu虽然我没有解释您的代码不起作用,我不清楚我的技术是否解决不了这个问题。使用无状态lambda强制ADL…
decltype(t)
So<代码>T?:)@巴里:这是从OP的原始问题复制/粘贴的清理干净了。@Yakk由于您的更改,我设法编译了它,但我不得不使用c++17和一些小的更改。如果我错了,请纠正我,但在c++14中不能有constexpr lambda函数。@HoratiuvCulture啊,我错过了constexpr。你可以编写一个相当于lambda的手动代码,也就是constexpr,它只是更加冗长而已。
template <typename T>
void foo(T t) {
   void(*f)(T) = +[](T x){ return g(std::forward<T>(x)); };
   f(t); //This compiles
   g(t); //This compiles
}
template <class T>
struct TypeResolution;

template <class T>
struct TypeResolution<T&>:TypeResolution<T> {};

template <class T>
struct TypeResolution {
  typedef const T* type;
  static constexpr void (*func_ptr)(type) = +[](type x){ return g(x); };
  static constexpr void *func_ptr_void = (void*)func_ptr;
};
template <class T>
struct TypeResolution {
  typedef const T* type;
  static void invoke_g(type t) { g( t ); }
  static constexpr void (*func_ptr)(type) = invoke_g;
  static constexpr void *func_ptr_void = (void*)func_ptr;
};
#include <iostream>
#include <type_traits>
#include <string>

void g(int*) {}

template <typename T>
struct TypeResolution;

template <typename T>
struct TypeResolution<T&> {
    struct Inner {
        static constexpr void foo(T* t) { g(t); }
    };
    static constexpr void *func_ptr_void = (void*)Inner::foo;
};

template <typename T>
struct TypeResolution {
    struct Inner {
        static constexpr void foo(T* t) { g(t); }
    };
    static constexpr void *func_ptr_void = (void*)Inner::foo;
};

void foo_impl(void *func_args[], void *data_args[]) {
    //Some work here, that will be in a different file or library
}

template <typename... ARGS>
void foo(ARGS && ... args) {
    void *func_ptrs[] = { TypeResolution<ARGS>::func_ptr_void... };
    void *args_ptrs[] = {(void*)&args...};
    foo_impl(func_ptrs, args_ptrs);
}

struct MyClass {};
void g(const MyClass*) {}

int main(int argc, char* argv[]) {
    int i = 1;
    foo(i);

    MyClass c;
    foo(c);
}