我使用了新的C++ 11「枚舉類」類型,並在使用g ++時觀察到「未定義參考」問題。這個問題在clang ++中不會發生。我不知道我是否做錯了什麼,或者如果它是一個g ++的錯誤。C++ 11,枚舉類,使用g ++的未定義參考,與clang一起使用++
要重現這裏的問題是代碼:(4個文件:enum.hpp,enum.cpp,main.cpp中和Makefile文件)
// file: enum.hpp
enum class MyEnum {
val_1,
val_2
};
template<typename T>
struct Foo
{
static const MyEnum value = MyEnum::val_1;
};
template<>
struct Foo<int>
{
static const MyEnum value = MyEnum::val_2;
};
template<typename T>
void foo(const T&);
和...
// file: enum.cpp
#include <iostream>
#include "enum.hpp"
template<typename T>
void foo(const T&)
{
switch(Foo<T>::value) {
case MyEnum::val_1:
std::cout << "\n enum is val_1"; break;
case MyEnum::val_2:
std::cout << "\n enum is val_2"; break;
default:
std::cout << "\n unknown enum"; break;
}
}
// Here we force instantation, thus everything should be OK!?!
//
template void foo<int>(const int&);
template void foo<double>(const double&);
和...
// file: main.cpp
#include "enum.hpp"
int
main()
{
foo(2.);
foo(2);
}
和Makefile文件...
COMPILER = g++ # does no work
#COMPILER = clang++ # Ok
all: main
main : main.cpp enum.cpp
$(COMPILER) -std=c++11 -c enum.cpp -o enum.o
$(COMPILER) -std=c++11 main.cpp enum.o -o main
當我使用克+ +我得到:
make -k
g++ -std=c++11 -c enum.cpp -o enum.o
g++ -std=c++11 main.cpp enum.o -o main
enum.o: In function `void foo<int>(int const&)':
enum.cpp:(.text._Z3fooIiEvRKT_[_Z3fooIiEvRKT_]+0xe): undefined reference to `Foo<int>::value'
enum.o: In function `void foo<double>(double const&)':
enum.cpp:(.text._Z3fooIdEvRKT_[_Z3fooIdEvRKT_]+0xe): undefined reference to `Foo<double>::value'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
make: Target `all' not remade because of errors.
但隨着鏗鏘++一切正常(無編譯錯誤)。
任何解釋都是值得歡迎的,因爲我迷失在這裏。
謝謝! :)
關於我的配置:
g++ --version
g++ (Debian 4.7.2-5) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
clang++ --version
Debian clang version 3.0-6 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
uname -a
Linux IS006139 3.2.0-4-amd64 #1 SMP Debian 3.2.35-2 x86_64 GNU/Linux
可能是一個編譯器錯誤。我希望在'switch(constant_expression)'中,「將左值到右值的轉換立即應用於'constant_expression'並且它不是一個odr使用,但是這很難證明。 – aschepler
我忘了提及的是,如果您刪除「class」關鍵字並使用舊式枚舉(enum MyEnum {val_1,val_2};),一切正常...... –