从元组获取元素 [英] getting an element from a tuple
问题描述
可能重复:
为什么ADL找不到函数模板?
调用 get
似乎不调用依赖于参数的查找:
t = std :: make_tuple(false,false,true);
bool a = get< 0>(t); // error
bool b = std :: get< 0>(t); // okay
g ++ 4.6.0说:
错误:'get'未在此范围内声明
Visual Studio 2010说:
错误C2065:'get':undeclared identifier
为什么?
解决方案通过提供
0
作为模板参数,显式地实例化get
在模板的情况下,如果具有该名称的功能模板在调用点可见,则ADL工作。这个可见的函数模板只能帮助触发 ADL(它可能不会实际使用),然后在其他命名空间中找到最佳匹配。
请注意,触发(或启用)ADL的功能模板不需要定义:
命名空间M
{
struct S {};
template< int N,typename T>
void get(T){}
}
命名空间N
{
template< typename T>
void get(T); //不需要提供定义
//只要启用ADL就可以了!
}
void f(M :: S s)
{
get< 0> // does not work - name`get`在这里不可见
}
void g(M :: S s)
{
使用N ::得到; // enable ADL
get< 0>(s); // calls M :: get
}
在
g )
时,名称N :: get
在调用get< 0>时触发ADL
。
C ++(2003)第§14.8.1/ 6节,
[注意:对于简单的函数名,参数依赖查找(3.4.2)即使在调用范围内函数名不可见时也适用。这是因为调用仍然具有函数调用的语法形式(3.4.1)。 但是,当使用具有显式模板参数的函数模板时,调用不具有正确的语法形式,除非在调用点处有可见的名称的函数模板。如果没有可见的此类名称,则调用的语法格式不正确,并且参数依赖的查找不适用。如果某些此类名称可见,则应用参数依赖查找,并且可能在其他命名空间中找到附加函数模板。
[示例:
命名空间A {
struct B {};
template< int X> void f(B);
}
命名空间C {
template< class T> void f(T t);
}
void g(A :: B b){
f 3(b); //形式:不是函数调用
A :: f 3(b); // well-formed
C :: f 3(b); //形成错误参数依赖查找
//仅适用于非限定名称
使用C :: f;
f 3(b); //形式良好,因为C :: f是可见的;那么
// A :: f由参数依赖查找找到
}
-end example] -end note]
Possible Duplicate:
Why doesn't ADL find function templates?Calling
get
does not seem to invoke argument dependent lookup:auto t = std::make_tuple(false, false, true); bool a = get<0>(t); // error bool b = std::get<0>(t); // okay
g++ 4.6.0 says:
error: 'get' was not declared in this scope
Visual Studio 2010 says:
error C2065: 'get': undeclared identifier
Why?
解决方案It's because you attempt to explicitly instantiate
get
function template, by providing0
as template argument. In case of templates, ADL works if a function template with that name is visible at the point of the call. This visible function template only helps triggering ADL (it may not be used actually) and then, a best matching can be found in other namespaces.Note that the function template which triggers (or enable) ADL, need not to have definition:
namespace M { struct S{}; template<int N, typename T> void get(T) {} } namespace N { template<typename T> void get(T); //no need to provide definition // as far as enabling ADL is concerned! } void f(M::S s) { get<0>(s); //doesn't work - name `get` is not visible here } void g(M::S s) { using N::get; //enable ADL get<0>(s); //calls M::get }
In
g()
, the nameN::get
triggers ADL when callingget<0>(s)
.Demo : http://ideone.com/83WOW
C++ (2003) section §14.8.1/6 reads,
[Note: For simple function names, argument dependent lookup (3.4.2) applies even when the function name is not visible within the scope of the call. This is because the call still has the syntactic form of a function call (3.4.1). But when a function template with explicit template arguments is used, the call does not have the correct syntactic form unless there is a function template with that name visible at the point of the call. If no such name is visible, the call is not syntactically well-formed and argument-dependent lookup does not apply. If some such name is visible, argument dependent lookup applies and additional function templates may be found in other namespaces.
[Example:
namespace A { struct B { }; template<int X> void f(B); } namespace C { template<class T> void f(T t); } void g(A::B b) { f<3>(b); //ill-formed: not a function call A::f<3>(b); //well-formed C::f<3>(b); //ill-formed; argument dependent lookup // applies only to unqualified names using C::f; f<3>(b); //well-formed because C::f is visible; then // A::f is found by argument dependent lookup }
—end example] —end note]
这篇关于从元组获取元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!