我有::tensor::contract
和::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
};
};
为什么我会在contract_expression::evaluate
中出现歧义?我相当确定没有流浪using
指令。
错误:
../../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_> >]
答案 0 :(得分:5)
通过ADL,在解析非限定函数调用时会考虑关联的命名空间。该行中至少有一个参数与详细命名空间相关联。
好的,我明白了。这些类型是否继承自详细信息类是否重要? - aaa
是的,基类是用于名称查找的关联类。考虑基类名称空间中的函数(§3.4.2/ 2,第二个项目符号点)。
如果要强制使用:: tensor :: contract,请不要使用非限定名称:
::tensor::contract(alpha * alpha_, a, b, beta, c);
或者将函数名称括在括号中,这会禁用ADL:
(contract)(alpha * alpha_, a, b, beta, c);
答案 1 :(得分:3)
第一候选人将有ADL(Argument Dependent Lookup,或Koening的查找)。在没有看到这些模板如何被实例化的情况下很难说,但是为了参数,如果函数的一个参数恰好来自detail
命名空间,那么该命名空间将被添加到查找中
这类似于您可能习惯的东西:
namespace test {
struct X {};
std::ostream& operator<<( std::ostream&, X const & ) {}
}
int main() {
test::X x;
std::cout << x; // [1]
}
在标有[1]的行中,代码位于全局命名空间中,但它在operator<<
命名空间内找到test
。原因是x
是该调用的参数,类型为test::X
,因此编译器会查找test
命名空间。