/ / Niejednoznaczność przestrzeni nazw C ++ - c ++

Niejednoznaczność przestrzeni nazw C ++ - c ++

mam obydwa ::tensor::contract i ::tensor::detail::contract

#include "tensor/detail/contract.hpp"

namespace tensor {


template<typename Alpha, class A, class B, typename Beta, class C>
void contract(Alpha alpha, A a, B b, Beta beta, C c) {
detail::contract(alpha, a, b, beta, c);
}

template<class A, class B, typename U = int>
struct contract_expression :
expression<contract_expression<A,B,U> >
{
template<typename T, class C>
void evaluate(T alpha, T beta, expression<C> &c) const {
contract(alpha*alpha_, a, b, beta, c); // ambiguity here
};
};

dlaczego dostaję niejednoznaczności contract_expression::evaluate? Jestem prawie pewien, że nie ma bezpańskich using dyrektywa.

błąd:

 ../../src/tensor/contract.hpp:12: note: candidates are: void tensor::contract(Alpha, A, B, Beta, C) [with Alpha = int, A = tensor::tensor_view<boost::detail::multi_array::multi_array_view<d
ouble, 2u>, boost::fusion::map<tensor::index<98, tensor::detail::index_range>, tensor::index<97, tensor::detail::index_range>, boost::fusion::void_, boost::fusion::void_, boost::fusion::voi
d_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, B = tensor::tensor_view<boost::detail::multi_array::multi_array_view<dou
ble, 3ul>, boost::fusion::map<tensor::index<97, tensor::detail::index_range>, tensor::index<99, tensor::detail::index_range>, tensor::index<100, tensor::detail::index_range>, boost::fusion:
:void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, Beta = int, C = tensor::tensor_view<boost::det
ail::multi_array::multi_array_view<double, 3ul>, boost::fusion::map<tensor::index<98, tensor::detail::index_range>, tensor::index<99, tensor::detail::index_range>, tensor::index<100, tensor
::detail::index_range>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >]
../../src/tensor/detail/contract.hpp:109: note:                 void tensor::detail::contract(Alpha, A, B, Beta, C) [with Alpha = int, A = tensor::tensor_view<boost::detail::multi_array::mu
lti_array_view<double, 2u>, boost::fusion::map<tensor::index<98, tensor::detail::index_range>, tensor::index<97, tensor::detail::index_range>, boost::fusion::void_, boost::fusion::void_, bo
ost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, B = tensor::tensor_view<boost::detail::multi_array::mult
i_array_view<double, 3ul>, boost::fusion::map<tensor::index<97, tensor::detail::index_range>, tensor::index<99, tensor::detail::index_range>, tensor::index<100, tensor::detail::index_range>
, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, Beta = int, C = tensor::tensor
_view<boost::detail::multi_array::multi_array_view<double, 3ul>, boost::fusion::map<tensor::index<98, tensor::detail::index_range>, tensor::index<99, tensor::detail::index_range>, tensor::i
ndex<100, tensor::detail::index_range>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::vo
id_> >]

Odpowiedzi:

5 dla odpowiedzi № 1

Przez ADLpowiązane przestrzenie nazw są uwzględniane podczas rozwiązywania niewykwalifikowanego wywołania funkcji. Przynajmniej jeden z parametrów tej linii jest powiązany z przestrzenią nazw szczegółów.

dobra, widzę. ma znaczenie, czy te typy dziedziczą z klas szczegółów? - aaa

Tak, klasy podstawowe są klasami powiązanymi dla celów wyszukiwania nazw. Uwzględniane są funkcje w przestrzeniach nazw klas bazowych (§3.4.2 / 2, drugi punktor).

Jeśli chcesz wymusić :: tensor :: contract do użycia, nie używaj niewykwalifikowanej nazwy:

::tensor::contract(alpha * alpha_, a, b, beta, c);

Lub zawiń nazwę funkcji w nawiasach, co wyłącza ADL:

(contract)(alpha * alpha_, a, b, beta, c);

3 dla odpowiedzi № 2

Kandydatem numer jeden będzie ADL (ArgumentWyszukiwanie zależne lub wyszukiwanie Koeninga. Nie widząc, w jaki sposób tworzone są te szablony, trudno jest powiedzieć, ale ze względu na argument, jeśli jednym z argumentów dotyczących twojej funkcji jest pochodzący z wewnątrz detail przestrzeń nazw, wtedy ta przestrzeń nazw zostanie dodana do odnośnika.

Jest to podobne do czegoś, do czego możesz być przyzwyczajony:

namespace test {
struct X {};
std::ostream& operator<<( std::ostream&, X const & ) {}
}
int main() {
test::X x;
std::cout << x; // [1]
}

W linii oznaczonej [1] kod znajduje się w globalnej przestrzeni nazw, a jednak znajduje operator<< w środku test przestrzeń nazw. Powód jest taki, że x jest argumentem do tego połączenia, a typ jest test::X, więc kompilator wyszukuje test przestrzeń nazw.