从元组获取元素 [英] getting an element from a tuple

查看:145
本文介绍了从元组获取元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

为什么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



演示: http://ideone.com/83WOW






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 providing 0 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 name N::get triggers ADL when calling get<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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆