对 class 模板的静态变量的未定义引用
Undefined reference to static variable of a class template
下面是我的代码:
// types.h
template <typename T>
struct type_to_char {};
template <>
struct type_to_char<char> {
static constexpr char str[] = "baz";
};
// main.cpp
#include <iostream>
#include <string>
#include "types.h"
int main() {
std::cout << type_to_char<char>::str << std::endl;
return 0;
}
在尝试编译时,链接器returns出错:
undefined reference to type_to_char<char>::str
我遇到过this answer,但我不确定如何在我的案例中应用它,因为模板没有编译。我应该在项目中放置一个单独的 .cpp
文件吗?
constexpr
变量的声明和定义有什么区别?这样的变量不能在没有初始化器的情况下声明,所以我为什么要在 .cpp
文件中单独定义?
我希望能对此做出一些澄清
您需要在最终程序中链接的 .cpp 中提供定义。例如:
// types.h
template <typename T>
struct type_to_char {};
template <>
struct type_to_char<char> {
static constexpr const char str[] = "baz";
};
// main.cpp
#include <iostream>
#include <string>
#include "types.h"
constexpr const char type_to_char <char>::str[];
int main() {
std::cout << type_to_char<char>::str << std::endl;
}
由于您完全特化了 class,它在许多方面表现得像未模板化的 class。一个例子是它的静态成员必须在实现文件中实例化,就像非模板化 classes.
// header file (type.h)
template <typename T>
struct type_to_char {};
template <>
struct type_to_char<char> {
static constexpr char str[] = "baz";
};
// impementation file (type.cpp)
constexpr char type_to_char <char>::str[];
// main.cpp
#include <iostream>
#include <type.h>
int main() {
std::cout << type_to_char<char>::str << std::endl;
return 0;
}
您不能 odr-use 静态 constexpr 数据成员,除非您为其提供定义。
当您尝试执行此操作时,会尝试使用它:
std::cout << type_to_char<char>::str << std::endl;
这就是为什么需要定义的原因。
您可以轻松重现问题,如下所示:
struct S { static constexpr int x = 0; };
int main() { auto y = &S::x; (void)y; }
无论如何,在您的特定情况下,使用以下声明就足够了:
static constexpr char *str = "baz";
如果可以使用它代替数组类型,则不必显式定义type_to_char<char>::str
。
下面是我的代码:
// types.h
template <typename T>
struct type_to_char {};
template <>
struct type_to_char<char> {
static constexpr char str[] = "baz";
};
// main.cpp
#include <iostream>
#include <string>
#include "types.h"
int main() {
std::cout << type_to_char<char>::str << std::endl;
return 0;
}
在尝试编译时,链接器returns出错:
undefined reference to type_to_char<char>::str
我遇到过this answer,但我不确定如何在我的案例中应用它,因为模板没有编译。我应该在项目中放置一个单独的 .cpp
文件吗?
constexpr
变量的声明和定义有什么区别?这样的变量不能在没有初始化器的情况下声明,所以我为什么要在 .cpp
文件中单独定义?
我希望能对此做出一些澄清
您需要在最终程序中链接的 .cpp 中提供定义。例如:
// types.h
template <typename T>
struct type_to_char {};
template <>
struct type_to_char<char> {
static constexpr const char str[] = "baz";
};
// main.cpp
#include <iostream>
#include <string>
#include "types.h"
constexpr const char type_to_char <char>::str[];
int main() {
std::cout << type_to_char<char>::str << std::endl;
}
由于您完全特化了 class,它在许多方面表现得像未模板化的 class。一个例子是它的静态成员必须在实现文件中实例化,就像非模板化 classes.
// header file (type.h)
template <typename T>
struct type_to_char {};
template <>
struct type_to_char<char> {
static constexpr char str[] = "baz";
};
// impementation file (type.cpp)
constexpr char type_to_char <char>::str[];
// main.cpp
#include <iostream>
#include <type.h>
int main() {
std::cout << type_to_char<char>::str << std::endl;
return 0;
}
您不能 odr-use 静态 constexpr 数据成员,除非您为其提供定义。
当您尝试执行此操作时,会尝试使用它:
std::cout << type_to_char<char>::str << std::endl;
这就是为什么需要定义的原因。
您可以轻松重现问题,如下所示:
struct S { static constexpr int x = 0; };
int main() { auto y = &S::x; (void)y; }
无论如何,在您的特定情况下,使用以下声明就足够了:
static constexpr char *str = "baz";
如果可以使用它代替数组类型,则不必显式定义type_to_char<char>::str
。