提问人:mk_g_d 提问时间:7/19/2023 最后编辑:JeJomk_g_d 更新时间:7/19/2023 访问量:27
尝试在 C++ 中使用 std::enable_if 有条件地定义成员函数时编译程序失败
Failed to compile program when trying to define member function conditionally using std::enable_if in C++
问:
我像往常一样编写一个带有一些成员函数的简单类,这次我尝试仅在类的模板参数满足某些条件时定义成员函数,但代码似乎无法在 g++ 和 vs2019 中编译。最简单的演示是这样的:
#include <type_traits>
template <int RowCnt, int ColCnt, typename ValueType = double>
class Matrix {
public:
template <std::enable_if_t<RowCnt == ColCnt, int> = 0>
void GetInverseMatrix() {}
private:
ValueType data[RowCnt][ColCnt];
};
int main() {
Matrix<3, 3> a;
Matrix<3, 5> b; // Compilation would fail here
return 0;
}
g++ 的错误输出如下所示:
test_enable_if_valid.cc: In instantiation of ‘class Matrix<3, 5>’:
test_enable_if_valid.cc:15:16: required from here
test_enable_if_valid.cc:7:8: error: no type named ‘type’ in ‘struct std::enable_if<false, int>’
7 | void GetInverseMatrix() {}
|
虽然 vs2019 讲述了类似的事情:
1>D:\labs\enable_if_test_1\main.cpp(7,1): error C2938: 'std::enable_if_t<false,int>' : Failed to specialize alias template
1>D:\labs\enable_if_test_1\main.cpp(6,17): message : see reference to alias template instantiation 'std::enable_if_t<false,int>' being compiled
1>D:\labs\enable_if_test_1\main.cpp(15,15): message : see reference to class template instantiation 'Matrix<3,5,double>' being compiled
在我看来,编译器本可以跳过函数的编译,因为没有调用,或者除非 SFINA 规则应该起作用。你能告诉我为什么我错了,或者为什么编译器的行为与我上面的期望不同吗?GetInverseMatrix()
Matrix<3, 5>::GetInverseMatrix()
提前感谢您,任何信息将不胜感激!
答:
2赞
n. m. could be an AI
7/19/2023
#1
SFINAE 在将显式指定或推导的模板参数替换为模板参数时起作用。
函数模板有一个模板参数,参数本身是无效的,除非 ,甚至在发生任何替换之前。GetInverseMatrix
RowCnt == ColCnt
模板参数的有效性可能取决于同一模板的前面的模板参数,因此可以:
template <int a, std::enable_if_t<a==42, int> = 0>
void foo() {}
但这是不行的:
template <int a>
struct bar
{
template <std::enable_if_t<a==42, int> = 0>
void foo() {}
};
bar<0> b;
未调用的函数模板不会实例化,但任何函数模板都必须至少具有有效的模板参数列表。
编写此模板的一种方法是
template<int R = RowCnt, int C = ColCnt>
std::enable_if_t<R == C>
GetInverseMatrix() {}
上一个:替换失败导致编译错误
评论