如何解决模板函数调用歧义?

时间:2011-08-22 12:01:13

标签: c++

我想创建一个函数conj,只有当参数的类型不是std::complex<T>时才会应用它。我可以使用enable_if,但我需要吗?

如果我有以下内容:

namespace{ 
    template<typename T> 
    T conj (T x) { 
        return x; 
    } 
}

我们已经进入std

template<typename T> 
std::complex<T> conj (std::complex<T> x);

conj(z) z std::complex<double> {{1}}的调用是否会被解析为std版本(因为这是'更好'的匹配?)

1 个答案:

答案 0 :(得分:4)

  

对于z是std :: complex的conj(z)调用是否会被解析为std版本(因为它是'更好'的匹配?)

是。这称为Argument Dependent-name Lookup。简称ADL,也称为 Koenig查找

  

我想创建一个函数conj,只有当参数的类型不是std :: complex时才会应用它。我可以使用enable_if,但我需要吗?

没什么。在命名空间内定义它,比如说me。如果参数的类型未在同一名称空间中定义,则使用qualified-name,或者如果 ,则可以使用非限定名称参数在同一名称空间中定义。在后一种情况下利用ADL。这是一个例子:

#include <iostream>
#include <complex>

namespace me
{ 
   template<typename T> 
    T conj (T x) 
    {
       std::cout << "me::conj" << std::endl;  
       return x; 
    } 
    struct A{};
}

struct B{};

int main() 
{
   std::complex<int> z(1,1);
   conj(z);  //calls std::conj due to ADL    

   me::A a; 
   conj(a); //unqualified-name : calls me::conj due to ADL

   me::conj(10); //qualified-name : ADL doesn't work with built-in types!

   B b; 
   me::conj(b); //qualified-name : B is not defined in 'me' namespace.
   return 0;
}

演示:http://www.ideone.com/0HRXr