问题描述
G ++和Clang ++同意以下代码段不是有效的C ++:
G++ and Clang++ agree that the following snippet is not valid C++:
template<int dim, int rank>
struct Tensor {};
template<int dim>
double InnerProduct(Tensor<dim, 1> const &, Tensor<dim, 1> const &)
{ return 0.0; }
template<int dim>
double DoubleInnerProduct(Tensor<dim, 2> const &, Tensor<dim, 2> const &)
{ return 0.0; }
template<int dim, int rank>
class Field
{
private:
static double Dot(Tensor<dim, rank> const &u, Tensor<dim, rank> const &v) requires (rank == 1)
{ return InnerProduct(u, v); }
static double Dot(Tensor<dim, rank> const &u, Tensor<dim, rank> const &v) requires (rank == 2)
{ return DoubleInnerProduct(u, v); }
};
template class Field<2, 1>;
template class Field<2, 2>;
错误消息指出,即使具有不满意约束的函数也会被实例化:
The error message states that even the functions with unsatisfied constraints are instantiated:
error: no matching function for call to ‘DoubleInnerProduct(const Tensor<2, 1>&, const Tensor<2, 1>&)’
22 | { return DoubleInnerProduct(u, v); }
我可以通过多种方式使它工作(例如,将 Dot
声明为模板,其默认参数等于对其施加约束的 rank
),但我希望它能工作.
I can make it work in a number of ways (for example, declaring Dot
as templates with a default parameter equal to rank
to which the constraints are applied), but I expected it to work.
通常,我是否应该假定无法显式实例化具有成员函数且其约束取决于模板参数的模板类?
In general, shall I assume that template classes with member functions with constraints depending on their template parameters cannot be explicitly instantiated?
推荐答案
这是GCC和Clang的c ++ 20实验性实现的错误.
This is a bug of the c++20 experimental implementation of both GCC and Clang.
这被报告为GCC 错误#77595 .
在c ++ 20段落[temp.explicit]/11中:
In the c++20 paragraph [temp.explicit]/11:
根据此c ++ 20附录假设该成员的关联约束(如果有)得到满足" 表示两个 Dot
中只有一个重载应显式实例化.
According to this c++20 adendum "provided that the associated constraints, if any, of that member are satisfied" means that only one of the two Dot
overload shall be explicitly instantiated.
加粗的子句",如下所述除外"在c ++ 17标准中.它确实适用于第一个子句"命名类模板专门化的显式实例化,也是其每个成员的相同类型(声明或定义)的显式实例".在c ++ 20中,此异常的解释未更改.语法上,可能是承诺者忽略了将异常应用于c ++ 20附录的正确做法.
The bolded clause "except as described below" was there in the c++17 standard. It does apply to the first clause "An explicit instantiation that names a class template specialization is also an explicit instantiation of the same kind (declaration or definition) of each of its members". The interpretation of this exception has not changed with c++20. Probably that the commitee overlooked that, grammaticaly, it could be correct to apply the exception to the c++20 adendum.
下面是 c ++ 17版本本段:
这句话较短,意思很清楚.
In this shorter sentence the meaning is clear.
这篇关于约束成员函数和显式模板实例化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!