【发布时间】:2017-12-13 23:39:52
【问题描述】:
我正在尝试理解名称查找和参数依赖查找。我创建了一个小示例。
已编辑:
#include <iostream>
void g(const int*) {}
template <typename T>
struct TypeResolution;
template <typename T>
struct TypeResolution<T&> {
typedef const T* type;
static constexpr void (*func_ptr)(TypeResolution::type) = g;
static constexpr void *func_ptr_void = (void*)func_ptr;
};
template <typename T>
struct TypeResolution {
typedef const T* type;
static constexpr void (*func_ptr)(TypeResolution::type) = g;
static constexpr void *func_ptr_void = (void*)func_ptr;
};
void foo_impl(void *[], void *[]) {
//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);
int j = 2;
foo(i, j);
MyClass c;
foo(c); //This fails.
}
所以我的问题是,为什么它不能编译?或者更简单地说,为什么在声明类而不是实例化类时会在 TypeResolution 中查找 g?正如我预期的那样在main函数里面然后看到函数void g(const MyClass*)
我想要获得的是能够为不同的不同类型调用不同的函数,但不需要转发声明它们。
我在 Ubuntu 16.04 上使用 g++ 5.4.0
【问题讨论】:
-
您的意思是说
&g编译不正确?没有g。 -
即使没有 c++ 标准集,您的代码也可以使用 vs 2017 (15.5.1)、VC 19.12.something 为我编译。
-
g_call取决于T- 但我不确定这有什么关系;您的问题不在于查找g_call,而是查找g。当它出现在函数调用中时,它会被查找两次——在定义点进行普通查找,在实例化点进行 ADL(找到它的是后者)。当它出现在&g中时,它不是一个从属名称,并且只在定义点查找一次。 -
@SornelHaetir 它之所以有效,是因为众所周知,MSVC 不实现两阶段查找,并将所有查找延迟到实例化点。只要
f未被实际使用,它就会愉快地编译template <typename T> void f() { random garbage here; }(Demo) -
您要求解决方法,但您没有描述您想要的。您只是显示无法编译的代码。我可以让你编译无数种方法,但没有线索知道你试图解决的潜在问题是什么,我不知道哪个子集对你有用(如果有的话),而且 SO 有一个帖子长度限制是有限的。
标签: c++ c++11 argument-dependent-lookup name-lookup