Tôi đang phát triển một dự án hoạt động với nhiều loại số học. Vì vậy, tôi đã thực hiện một tiêu đề, nơi các yêu cầu tối thiểu cho một người dùng định nghĩa kiểu số học được định nghĩa:Tại sao một số chức năng trong <cmath> không có trong không gian tên std?
user_defined_arithmetic.h:
typedef double ArithmeticF; // The user chooses what type he
// wants to use to represent a real number
namespace arithmetic // and defines the functions related to that type
{
const ArithmeticF sin(const ArithmeticF& x);
const ArithmeticF cos(const ArithmeticF& x);
const ArithmeticF tan(const ArithmeticF& x);
...
}
gì đang gây phiền toái cho tôi là khi tôi sử dụng mã như thế này:
#include "user_defined_arithmetic.h"
void some_function()
{
using namespace arithmetic;
ArithmeticF lala(3);
sin(lala);
}
tôi nhận được một lỗi biên dịch:
error: call of overloaded 'sin(ArithmeticF&)' is ambiguous
candidates are:
double sin(double)
const ArithmeticF arithmetic::sin(const ArithmeticF&)
Tôi chưa bao giờ sử dụng tiêu đề <math.h>
, chỉ có <cmath>
. Tôi chưa bao giờ sử dụng using namespace std
trong tệp tiêu đề.
Tôi đang sử dụng gcc 4.6. *. Tôi đã kiểm tra các tiêu đề có chứa các tuyên bố mơ hồ là gì và nó hóa ra là:
mathcalls.h:
Prototype declarations for math functions; helper file for <math.h>.
...
tôi biết, rằng <cmath>
bao gồm <math.h>
, nhưng nó phải che chắn các tờ khai do không gian tên std. Tôi thâm nhập vào các <cmath>
header và tìm thấy:
cmath.h:
...
#include <math.h>
...
// Get rid of those macros defined in <math.h> in lieu of real functions.
#undef abs
#undef div
#undef acos
...
namespace std _GLIBCXX_VISIBILITY(default)
{
...
Vì vậy, std namespace bắt đầu sau các #include <math.h>
. Có điều gì sai ở đây không, hay tôi đã hiểu nhầm điều gì đó?
Một số điều bạn có thể muốn xem xét lại: khi sử dụng các loại số học (không thể thiếu các loại + đôi + float) nó thường là hiệu quả hơn (và thông thường) để vượt qua giá trị so với tham chiếu. Khi gọi một hàm mà bạn muốn một phiên bản cụ thể, hãy hội đủ điều kiện cuộc gọi, thay vì thêm một 'không gian tên' X'. Hoặc bạn có thể sử dụng chỉ thị * bằng cách sử dụng * ('sử dụng số học :: sin'). Cuối cùng, toàn bộ cách tiếp cận của việc thay đổi kiểu bằng cách chỉnh sửa 'typedef' là một ý tưởng tồi. –
@ DavidRodriguez-dribeas: Cảm ơn bạn! Xin vui lòng, bạn có thể gợi ý cho tôi một giải pháp thay thế? Tôi đang sử dụng đi qua tham chiếu, bởi vì số lượng có thể là một loại tùy chỉnh. Điều đó có nghĩa là nó có thể nhận được vài kilobyte lớn. Tôi đã hy vọng rằng khi tôi inline các chức năng và sử dụng các chức năng cơ bản std bên trong nội tuyến, không có hại sẽ được thực hiện. Hay sẽ là? Bạn có thể cho tôi một số gợi ý xin vui lòng? –
@ DavidRodriguez-dribeas: Tôi biết rằng cách tiếp cận C++ sẽ là khai báo một lớp trừu tượng, nhưng một thư viện mà tôi sử dụng để tính toán ma trận sử dụng tối ưu hóa đáng kể khi bạn sử dụng một kiểu được xây dựng sẵn. Tôi chỉ không muốn mất lợi thế này –