使用template参数访问模板化类的模板化静态constexpr成员



所以我有一个模板化的类,它有一个模版化的static constexpr bool。设置可以归结为:

#include <type_traits>
template <typename T>
class A {
public:
template <typename U>
static constexpr bool same = std::is_same_v<T, U>;
};
template <typename T>
bool test() {
return A<T>::same<int>; // errors
}
int main() {
A<int>::same<int>;      // compiles perfectly
test<int>();            // errors
}

当我使用A<int>::same<int>等实际类型访问它时,它编译得很好,但当我尝试使用模板类型访问它(如上面的test()函数中所述(时,它会出错。以下是错误的完整列表:

constexpr_value.cpp: In function ‘bool test()’:
constexpr_value.cpp:12:21: error: expected primary-expression before ‘int’
12 |   return A<T>::same<int>;
|                     ^~~
constexpr_value.cpp:12:21: error: expected ‘;’ before ‘int’
12 |   return A<T>::same<int>;
|                     ^~~
|                     ;
constexpr_value.cpp:12:24: error: expected unqualified-id before ‘>’ token
12 |   return A<T>::same<int>;
|                        ^
constexpr_value.cpp: In instantiation of ‘bool test() [with T = int]’:
constexpr_value.cpp:16:12:   required from here
constexpr_value.cpp:12:16: error: ‘A<int>::same<U>’ missing template arguments
12 |   return A<T>::same<int>;
|                ^~~~

前三个错误来自模板本身,即使我根本不使用test()函数,它们也会显示出来,所以编译器似乎在检查任何特定的T之前就假设A<T>::same<int>是一个无效的语句。

我一点也不理解这些错误。为什么A<int>::same<int>编译完美,但一旦使用模板类型,它就一点也不喜欢它?我甚至不知道从哪里开始解决这个问题,因为错误告诉我什么都没有。编译和不编译之间的唯一区别是使用<T>而不是<int>,那么我能用T告诉编译器这是一个有效的语句吗?

模板代码不等同于A<int>::same<int>。这也将编译:

template <typename T>
bool test() {
return A<int>::same<int>;
}

返回错误代码。最新的GCC 12.1将在警告中产生提示:

constexpr_value.cpp: In function 'bool test()':
constexpr_value.cpp:12:16: warning: expected 'template' keyword before dependent template name [-Wmissing-template-keyword]
12 |   return A<T>::same<int>; // errors
|                ^~~~

正如警告消息所建议的修复方法:

template <typename T>
bool test() {
return A<T>::template same<int>;
}
//             ^^^^^^^^

看看热门问题我必须在哪里以及为什么要把";模板";以及";typename";关键词?了解更多信息。

最新更新