为什么 std::arrays 使用类型检查来破坏模板化函数?
Why do std::arrays break templated functions with type checks?
我有一个模板函数,它根据提供的类型执行某些操作:
template<typename T>
T read()
{
if (std::is_integral<T>()) {
return static_cast<T>(std::stoi(readToken()));
}
else if (std::is_same<T, float>()) {
return std::stof(readToken());
}
else if (std::is_same<T, std::array<float, 3>>()) {
return { read<float>, read<float>, read<float> };
}
else throw std::logic_error("Invalid type");
}
编译器在调用 read<int>()
时发出以下警告:
control reaches end of non-void function
read
是模板。每次实例化此模板时,编译器都会生成整个函数体。当您调用带有 array
的 read<int>()
部分时,也会编译,但无法将数组分配给 return 类型,即 int
。这就是您收到错误的原因。
在 g++7.3 下你可以使用 if constexpr 构造。这样,if 条件为真范围内的行仅被编译:
template<typename T>
T read() {
if constexpr (std::is_integral<T>()) {
return static_cast<T>(std::stoi(readToken()));
}
else if constexpr (std::is_same<T, float>()) {
return std::stof(readToken());
}
else if constexpr (std::is_same<T, std::array<float, 3>>()) {
std::array<float, 3> arr;
arr.at(0) = 4; arr.at(1) = 2; arr.at(2) = 0;
return arr;
}
else throw std::logic_error("Invalid type");
}
在 c++17 之前,您调用辅助函数,该函数为您要处理的所有类型重载:
template<class T>
T readHelper() {
throw std::runtime_error("invalid type");
}
// here provide types you want to be handled
template<>
int readHelper<int>() { return std::stoi(readToken()); }
template<>
float readHelper<float>() { return std::stof(readToken()); }
template<>
std::array<float,3> readHelper<std::array<float,3>>() {
return std::array<float,3>{};
}
template<class T>
T read2(){
return readHelper<T>();
}
我有一个模板函数,它根据提供的类型执行某些操作:
template<typename T>
T read()
{
if (std::is_integral<T>()) {
return static_cast<T>(std::stoi(readToken()));
}
else if (std::is_same<T, float>()) {
return std::stof(readToken());
}
else if (std::is_same<T, std::array<float, 3>>()) {
return { read<float>, read<float>, read<float> };
}
else throw std::logic_error("Invalid type");
}
编译器在调用 read<int>()
时发出以下警告:
control reaches end of non-void function
read
是模板。每次实例化此模板时,编译器都会生成整个函数体。当您调用带有 array
的 read<int>()
部分时,也会编译,但无法将数组分配给 return 类型,即 int
。这就是您收到错误的原因。
在 g++7.3 下你可以使用 if constexpr 构造。这样,if 条件为真范围内的行仅被编译:
template<typename T>
T read() {
if constexpr (std::is_integral<T>()) {
return static_cast<T>(std::stoi(readToken()));
}
else if constexpr (std::is_same<T, float>()) {
return std::stof(readToken());
}
else if constexpr (std::is_same<T, std::array<float, 3>>()) {
std::array<float, 3> arr;
arr.at(0) = 4; arr.at(1) = 2; arr.at(2) = 0;
return arr;
}
else throw std::logic_error("Invalid type");
}
在 c++17 之前,您调用辅助函数,该函数为您要处理的所有类型重载:
template<class T>
T readHelper() {
throw std::runtime_error("invalid type");
}
// here provide types you want to be handled
template<>
int readHelper<int>() { return std::stoi(readToken()); }
template<>
float readHelper<float>() { return std::stof(readToken()); }
template<>
std::array<float,3> readHelper<std::array<float,3>>() {
return std::array<float,3>{};
}
template<class T>
T read2(){
return readHelper<T>();
}