我遇到以下代碼在GCC(4.8+測試)和Clang(3.4+測試)編譯但未在Visual Studio 2015(VC++ 14.0)上編譯的問題。是否有效返回聲明的枚舉類? (Visual Studio 2015鏈接器錯誤)
foo.h中:
#include <functional>
namespace Error {
enum class Code;
static const Code None = static_cast<Code>(0);
}
class Foo{
public:
std::function<Error::Code()> Run();
};
Foo.cpp中
#include "Foo.h"
#include <iostream>
std::function<Error::Code()> Foo::Run() {
return [&]() {
std::cout << "hello\n";
return Error::None;
};
}
main.cpp中:
#include "Foo.h"
namespace Error {
enum class Code {
None = 0,
Error = 1,
};
}
int main() {
Foo foo;
foo.Run()();
}
在VC 14.0將得到的誤差如下:
Foo.obj : error LNK2001: unresolved external symbol "enum Error::Code __cdecl std::_Invoke_ret<enum Error::Code,class <lambda_813e82254384ef384f6a5fe34e885f01> &>(struct std::_Forced<enum Error::Code,0>,class <lambda_813e82254384ef384f6a5fe34e885f01> &)" ([email protected]@[email protected]@AAV<lambda_813e82254384ef384f6a5fe34e885f01>@@@[email protected]@[email protected]@@[email protected]@[email protected]@[email protected]@[email protected]<lambda_813e82254384ef384f6a5fe34e885f01>@@@Z)
我認爲這是一個內部std庫函數,用於實現std::function
。
此代碼類似於內部庫的用法我試圖使用它共享工具的標準程序接口,但前進聲明錯誤代碼,以便可以自定義它們。我相信這應該是基於§7.2的有效代碼(參見this answer)雖然前面聲明的枚舉應該是一個完整類型,並且可用作返回值。以下是標準中的相關位:
An opaque-enum-declaration is either a redeclaration of an enumeration in the current scope or a declaration of a new enumeration. [Note: An enumeration declared by an opaque-enum-declaration has fixed underlying type and is a complete type. The list of enumerators can be provided in a later redeclaration with an enum-specifier. —end note ]
此代碼是否有效?如果是這樣,是否有解決方法讓VC++接受它?
_「枚舉雖然是前向聲明的,應該是一個完整的類型並且可用作返回值。」_前向聲明不提供_complete types_ enum或不。 –
@πάνταῥεῖ這就是爲什麼這在技術上不是一個前向聲明,而是一個不透明枚舉聲明(如果甚至對「前向聲明」這個術語甚至有一個恰當的定義......)無論如何,這樣的聲明引入了* a完全枚舉類型*。枚舉有一個特殊的情況,IIRC永遠不會引入不完全的枚舉類型。 – dyp
你的'enum class Code' _definition_與你的_declared_'enum類不在同一個命名空間中Error :: Code' – inetknght