Visual C++ 2015では、C++11の属性構文とC++14のdeprecatedとnoreturnの属性に対応しています。すると気になるのがViusal C++がもともと持っていた属性構文との互換性です。
代わりになるのかどうか、まずはC++/CLIやC++/CXで試してみました。先に言ってしまうと、結果はダメでした。
1つ目として、main関数においてCOMのアパートメントを指定するSystem::STAThreadAttribute属性およびPlatform::STAThreadAttribute属性を試しました。
まず、C++/CLIのコードです。
// cl /clr a.cpp ole32.lib #include <iostream> #include <windows.h> using namespace std; using namespace System; //[[STAThread]] [STAThread] int main() { APTTYPE aptType; APTTYPEQUALIFIER aptQualifier; auto hr = CoGetApartmentType(&aptType, &aptQualifier); if (SUCCEEDED(hr)) { cout << boolalpha; cout << (aptType == APTTYPE_MAINSTA) << endl; cout << (aptType == APTTYPE_STA) << endl; } else { cout << "CoGetApartmentType failed: " << showbase << hex << hr << endl; } } |
[STAThread]
だと「true false」という出力で、メインSTAになっている結果です。一方、[[STAThread]]
だと「false false」で、MTA(.NET Frameworkのデフォルト)のようです。
次に、C++/CXのコードです。
// cl /ZW b.cpp #include <iostream> #include <windows.h> using namespace std; using namespace Platform; //[[STAThread]] [STAThread] int main() { APTTYPE aptType; APTTYPEQUALIFIER aptQualifier; auto hr = CoGetApartmentType(&aptType, &aptQualifier); if (SUCCEEDED(hr)) { cout << boolalpha; cout << (aptType == APTTYPE_MAINSTA) << endl; cout << (aptType == APTTYPE_STA) << endl; } else { cout << "CoGetApartmentType failed: " << showbase << hex << hr << endl; } } |
これも、[STAThread]
だと出力は「true false」で、メインSTAになっています。一方、[[STAThread]]
だと出力は「CoGetApartmentType failed: 0x800401f0」です。これはCO_E_NOTINITIALIZED、すなわちCOMの初期化がされていない状態です。
もう1つ試してみました。System::FlagsAttribute属性およびPlatform::Metadata::FlagsAttribute属性です。
こちらも、まずはC++/CLIのコードです。
using namespace System; [Flags] public enum class Hoge1 : unsigned { Foo = 0, Bar = 1, }; public enum class [[Flags]] Hoge2 : unsigned { Foo = 0, Bar = 1, }; void f() { auto a = Hoge1::Foo | Hoge1::Bar; auto b = Hoge2::Foo | Hoge2::Bar; } |
そして、C++/CXのコードです。
using namespace Platform::Metadata; namespace Hoge { [Flags] public enum class Hoge1 : unsigned { Foo = 0, Bar = 1, }; public enum class [[Flags]] Hoge2 : unsigned { Foo = 0, Bar = 1, }; void f() { auto a = Hoge1::Foo | Hoge1::Bar; auto b = Hoge2::Foo | Hoge2::Bar; } } |
何回かコンパイルを試した結果、「そうか、C++の属性はVC++のと指定する位置が異なるんだな」ということを知りました。それはともかく、やっぱり[[Flags]]
を使うHoge2はC++/CLIでもC++/CXでもダメでした。
というわけで、「C++/CLIおよびC++/CXでは、以前からある属性構文とC++11の属性構文とは別物である。互換ではないことが分かった」というお話でした。
2015年10月17日追記:FlagsのサンプルコードがC++/CLIとC++/CXで逆でしたので、掲載順序を直しました。
スポンサード リンク |