Tôi đã gặp sự cố tương tự trong quá khứ và đây là cách tôi đã khắc phục sự cố đó. Tôi muốn có thể chuyển đổi việc triển khai thư viện lúc biên dịch. Một trong những lib được sử dụng mã như thế này:
namespace Lib1
{
enum LibEnum { One, Two, Three };
[...]
void someFunc(LibEnum val);
}
Trong mã của tôi, tôi muốn che giấu việc thực hiện thư viện từ kinh nghiệm người dùng (do đó, một người sử dụng của mã của tôi không bao giờ nên xem những gì lib Tôi đang sử dụng trong nội bộ):
giải pháp 1:
namespace MyCode
{
// Example to avoid copying a function from Lib1 here
typedef Lib1::someFunc aFunctionImUsing;
// This doesn't work
// typedef LibEnum MyEnum;
// As such code doesn't compile:
// aFunctionImUsing(One); // Error unknown identifier One
// But this did:
struct Type
{
enum MyType { One = Lib1::One, Two = Lib1::Two, Three = Lib1::Three };
}
static inline Lib1::LibEnum as(Type::MyType t) { return (Lib1::LibEnum)t; }
// Now code like this compiles:
aFunctionImUsing(as(Type::One));
// This one doesn't:
// aFunctionImUsing(Type::One); // Can't convert from Type::MyType to Lib1::LibEnum
[...]
}
giải pháp 2:
namespace MyCode
{
struct Type
{
enum MyType { One = Lib1::One, Two = Lib1::Two, Three = Lib1::Three };
}
// If you don't care about polluting your namespace with numerous wrapper
// you can write this instead of typedef someFunc:
static inline void myFunc(Type::MyType t) { return Lib1::someFunc((Lib1::LibEnum)t); }
// This one does:
myFunc(Type::One);
[...]
}
Chúng là 2 vấn đề với đoạn mã ở trên.Vấn đề đầu tiên là bạn phải sao chép & dán enum bên trong không gian tên của bạn, (nhưng với một biểu thức chính quy đơn giản trong tìm thấy & thay thế, bạn đã hoàn tất). Vấn đề thứ hai là người dùng của bạn sẽ phải sử dụng phương thức "as", có nghĩa là nó không đơn giản, hoặc bạn phải bọc phương thức/hàm bằng cách sử dụng giải pháp thứ hai.
Dù sao, vì không thể tiêm một enum qua không gian tên, giải pháp này là tốt nhất bạn có thể làm. Lưu ý rằng người dùng mã của bạn thậm chí không biết bạn đang sử dụng thư viện Lib1 trong mã ví dụ.
Nguồn
2009-10-11 15:18:39
"Tôi đặc biệt không muốn nói A :: E1" - tại sao không? –
vì A được sử dụng trong một số lớp và tôi không muốn tham chiếu đến loại không liên quan. Trong thực tế sử dụng của tôi, A là một kiểu lồng nhau được đánh máy ở một nơi khác, và nó thực sự sẽ giống như N :: E :: C :: A :: E1 – rlbond
Sau đó, bạn sẽ phải tạo một không gian tên và xác định enum đó. Tại sao không làm điều đó? –