为什么参数依赖查找不与函数模板dynamic_pointer_cast一起使用 [英] Why Argument Dependent Lookup doesn't work with function template dynamic_pointer_cast

查看:649
本文介绍了为什么参数依赖查找不与函数模板dynamic_pointer_cast一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下C ++程序:

  #include< memory> 

struct A {};

struct B:A {};

int main()
{
auto x = std :: make_shared< A>();
if(auto p = dynamic_pointer_cast< B>(x));
}

在使用MSVC 2010编译时,我会收到以下错误:

 错误C2065:'dynamic_pointer_cast':未声明的标识符

如果 auto std :: shared_ptr< A> 替换,则错误仍然存​​在。当我使用 std :: dynamic_pointer_cast 完全限定调用时,程序会成功编译。



=http://ideone.com/Z28dC> gcc 4.5.1 不喜欢:

 错误:'dynamic_pointer_cast'未在此范围内声明

我认为 std :: dynamic_pointer_cast 会被 Koenig查询选中,因为类型 x 位于 std 命名空间中。

解决方案

我认为第14.8.1节/6节(C ++ 03, (注意:对于简单的函数名,依赖于参数的查找(参数依赖查找) 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]


您的案例不会触发ADL,因为您显式传递模板参数 strong>在您调用 dynamic_pointer_cast 的网站上没有可用的相同名称的模板。



enable ADL is to add a dummy template with same name to your code,如下所示:

  #include< memory> 

struct A {};

struct B:A {};

template< int> //模板参数可以是任何东西!
void dynamic_pointer_cast(); // ADD this。不需要定义它

int main()
{
auto x = std :: make_shared< A>();
if(auto p = dynamic_pointer_cast< B>(x)); // now it should work through ADL
}


Consider the following C++ program:

#include <memory>

struct A {};

struct B : A {};

int main()
{
    auto x = std::make_shared<A>();
    if (auto p = dynamic_pointer_cast<B>(x));
}

When compiling with MSVC 2010, I obtain the following error:

error C2065: 'dynamic_pointer_cast' : undeclared identifier

The error persists if auto is replaced by std::shared_ptr<A>. When I fully qualify the call with std::dynamic_pointer_cast, the program successfully compiles.

Also, gcc 4.5.1 doesn't like it either:

error: 'dynamic_pointer_cast' was not declared in this scope

I thought that std::dynamic_pointer_cast would have been picked by Koenig lookup, since the type of x lives in the std namespace. What am I missing here ?

解决方案

I think section §14.8.1/6 (C++03, and I think it holds in C++11 also) applies to this case which reads as,

[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]

Your case do not trigger ADL because you explicitly pass template argument and there is no template with the same name available at the site where you call dynamic_pointer_cast.

One trick to enable ADL is to add a dummy template with same name to your code, as shown below:

#include <memory>

struct A {};

struct B : A {};

template<int> //template parameter could be anything!
void dynamic_pointer_cast(); //ADD this. NO NEED TO DEFINE IT

int main()
{
   auto x = std::make_shared<A>();
   if (auto p = dynamic_pointer_cast<B>(x)); //now it should work through ADL
}

这篇关于为什么参数依赖查找不与函数模板dynamic_pointer_cast一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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