Я хочу предоставить некоторые функции оболочки sqrt для simd-типов, чтобы их можно было использовать из шаблонов вместе со std :: sqrt.Почему clang не находит функцию, объявленную до места вызова?
Теперь у меня есть проблема, что они как-то не видны. Могут использоваться только те, которые определены в std.
Это очень уменьшенная часть коды:
#include <cmath>
#include <pmmintrin.h>
using float_simd = __m128;
using double_simd = __m128d;
float_simd sqrt(float_simd a) { return _mm_sqrt_ps(a); }
double_simd sqrt(double_simd a) { return _mm_sqrt_pd(a); }
template <typename T>
void do_fancy(T val)
{
using std::sqrt;
auto ret = sqrt(val);
(void)ret;
}
int main() {
double testDouble = 1.0;
float testFloat = 1.0f;
double_simd testSimdDouble;
float_simd testSimdFloat;
do_fancy(testDouble);
do_fancy(testFloat);
do_fancy(testSimdDouble);
do_fancy(testSimdFloat);
return 0;
}
Теперь лязг дает это:
main.cpp:14:16: error: call to function 'sqrt' that is neither visible in the template definition nor found by argument-dependent lookup
auto ret = sqrt(val);
^
main.cpp:25:5: note: in instantiation of function template specialization 'do_fancy<__attribute__((__vector_size__(2 * sizeof(double)))) double>' requested here
do_fancy(testSimdDouble);
^
main.cpp:8:13: note: 'sqrt' should be declared prior to the call site
double_simd sqrt(double_simd a) { return _mm_sqrt_pd(a); }
^
main.cpp:14:16: error: call to function 'sqrt' that is neither visible in the template definition nor found by argument-dependent lookup
auto ret = sqrt(val);
^
main.cpp:26:5: note: in instantiation of function template specialization 'do_fancy<__attribute__((__vector_size__(4 * sizeof(float)))) float>' requested here
do_fancy(testSimdFloat);
^
main.cpp:7:12: note: 'sqrt' should be declared prior to the call site
float_simd sqrt(float_simd a) { return _mm_sqrt_ps(a); }
^
Он говорит, что функции SQRT SIMD «должны быть объявлены до сайта вызова» , но я думаю, что они есть.
Я сделал веб-поиск, но, к сожалению, я нашел случаи, когда порядок вызова и декларация на самом деле были неправильными.
Я только что прокомментировал using std::sqrt
и все работает нормально. Я не понимаю ... Как он теперь может найти std :: sqrt?
Я использую clang 3.9.1 из homebrew на macOS.
Да. Имя учебника скрывается. По той же причине (ish), что вы иногда должны использовать гипс 'using Base :: foo' в своих классах. Определенно не интуитивно понятный для начинающего C++, но вы в конце концов привыкаете к нему. –
хорошо, правильно, я понимаю ... Вы также знаете, почему это работает, когда комментируете 'using std :: sqrt' целиком? – thorink
@thorink, потому что «вам нужно сделать:» часть ответа не требуется. Поиск имени будет искать sqrt, который фактически находится в глобальном пространстве имен, так как C определил его таким образом в своей стандартной библиотеке. – iheanyi