admin管理员组文章数量:1313752
I've been playing around with C++20 concepts and ran into an issue with my GCC 9.4 compiler, which I ultimately want to support. I created this minimal reproducible example to showcase the problem:
#include <iostream>
#include <type_traits>
template <typename T, typename Type>
concept IsSame = std::is_same_v<T, Type>;
template <typename Scalar>
class MyClass {
public:
template <typename T>
using ScalarT = T;
template <typename T>
requires IsSame<T, typename MyClass<Scalar>::template ScalarT<double>>
static void print(const T& b);
};
// Compilation depends on compiler
template<typename Scalar>
template<typename T>
requires IsSame<T, typename MyClass<Scalar>::template ScalarT<double>>
void MyClass<Scalar>::print(const T& t) {
std::cout << std::fixed << t << " as Scalar is " << std::fixed << static_cast<Scalar>(t) << std::endl;
}
int main() {
MyClass<int>::print(6.0);
return 0;
}
GCC 9.4 (with -std=c++2a -fconcepts
) and the more recent GCC 14.2 (with -std=c++20
) complain that:
<source>:334:6: error: no declaration matches 'void MyClass<Scalar>::print(const B&)'
334 | void MyClass<Scalar>::print(const B& b) {
| ^~~~~~~~~~~~~~~
<source>:327:17: note: candidate is: 'template<class Scalar> template<class T> requires IsSame<T, double> static void MyClass<Scalar>::print(const T&)'
327 | static void print(const T& b);
| ^~~~~
<source>:320:7: note: 'class MyClass<Scalar>' defined here
320 | class MyClass {
However, both GCC compilers are ok with defining the function inline, as:
template <typename T>
requires IsSame<T, typename MyClass<Scalar>::template ScalarT<double>>
static void print(const T& t) {
std::cout << std::fixed << t << " as Scalar is " << std::fixed << static_cast<Scalar>(t) << std::endl;
}
or
template <typename T>
requires IsSame<T, ScalarT<double>>
static void print(const T& t) {
std::cout << std::fixed << t << " as Scalar is " << std::fixed << static_cast<Scalar>(t) << std::endl;
}
Clang 19.1 (with -std=c++2a
) has no issue, and prints 6.000000 as Scalar is 6
.
I know I could also do the following:
template <IsSame<ScalarT<double>> T>
static void print(const T& t) {
std::cout << std::fixed << t << " as Scalar is " << std::fixed << static_cast<Scalar>(t) << std::endl;
}
But this has the same issue with GCC, where moving the implementation outside the class does not work:
template<typename Scalar>
template<IsSame<typename MyClass<Scalar>::template ScalarT<double>> T>
static void MyClass<Scalar>::print(const T& t) {
std::cout << std::fixed << t << " as Scalar is " << std::fixed << static_cast<Scalar>(t) << std::endl;
}
本文标签: GCC stricter than Clang for resolving dependent names for conceptsStack Overflow
版权声明:本文标题:GCC stricter than Clang for resolving dependent names for concepts - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741957800a2407089.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论