据我所知,标准中没有提及“ 完全合格 ”一词(例如),但我可以记得在网上多次“听到”它。
人们说一个名字完全合格是什么意思?
这算吗?
A::f()
Run Code Online (Sandbox Code Playgroud)
还是只有这个?
::A::f()
Run Code Online (Sandbox Code Playgroud)
而且,如果这是标准的,我找不到哪个措辞?
以下所有标准参考均指N4861(2020 年 3 月布拉格后工作草案/C++20 DIS)。
在问答中 无捕获的 lambda 是结构类型吗?很明显,某些 lambda 表达式具有关联的闭包类型,这些闭包类型是(文字和)结构类型,因此特定的此类闭包类型可以用作非类型模板参数;本质上将结构类型 lambda 作为非类型模板参数传递。
Run Code Online (Sandbox Code Playgroud)template<auto v> constexpr auto identity_v = v; constexpr auto l1 = [](){}; constexpr auto l2 = identity_v<l1>;
现在,根据[expr.prim.lambda.closure]/1 ,每个 lambda 表达式的类型都是唯一的
[...] 一个独特的、未命名的非联合类类型,称为闭包类型[...]
另一方面,[basic.def.odr]/1 [extract,强调我的]指出
任何翻译单元不得包含任何变量、函数、类类型、枚举类型、模板、参数的默认参数(对于给定范围内的函数)或默认模板参数的多个定义。
可以说,默认模板参数被认为是需要尊重 ODR 的定义。
...这引出了我的问题:
(如果接近非法,也请强调:例如,如果超出单个实例化的任何事情都会导致 ODR 违规)。
如果这实际上是合法的,则每次调用带有 lambda 作为默认参数的变量模板都会导致唯一特化的实例化:
template<auto l = [](){}>
// ^^^^^^ - lambda-expression as …
Run Code Online (Sandbox Code Playgroud) 使用Swift 2.2可以实现以下功能:
let m = "alpha"
for i in m.startIndex..<m.endIndex {
print(m[i])
}
a
l
p
h
a
Run Code Online (Sandbox Code Playgroud)
使用3.0,我们收到以下错误:
类型'范围'(又名'范围')不符合协议'序列'
我试图用swift中的字符串做一个非常简单的操作 - 只是遍历字符串的前半部分(或更普遍的问题:遍历字符串的范围).
我可以做以下事情:
let s = "string"
var midIndex = s.index(s.startIndex, offsetBy: s.characters.count/2)
let r = Range(s.startIndex..<midIndex)
print(s[r])
Run Code Online (Sandbox Code Playgroud)
但在这里,我并没有真正遍历字符串.所以问题是:如何遍历给定字符串的范围.喜欢:
for i in Range(s.startIndex..<s.midIndex) {
print(s[i])
}
Run Code Online (Sandbox Code Playgroud) 以下所有标准参考均指N4659:2017 年 3 月后 Kona 工作草案/C++17 DIS。
考虑以下片段:
#include <type_traits>
template <int N> struct num {};
template <typename> struct A;
// (1)
template <int N> struct A<num<N>> { using type = bool; };
// (2)
template <long N> struct A<num<N>> { using type = char; };
static_assert(!std::is_same_v<long, int>, "");
// (A)
static_assert(std::is_same_v<A<num<1>>::type, bool>, "");
int main() {}
Run Code Online (Sandbox Code Playgroud)
将static_assert
在(A)是成功的GCC,但失败了锵:
Run Code Online (Sandbox Code Playgroud)error: static_assert failed due to requirement 'std::is_same_v<char, bool>' ""
本质上,GCC 选择完美匹配的专业化(1),而 Clang 选择专业化(2) …
在cppreference的语言参考中std::enable_if
包括以下注释
笔记
一个常见的错误是声明两个仅在默认模板参数上有所不同的函数模板.这是非法的,因为默认模板参数不是函数模板签名的一部分,并且声明具有相同签名的两个不同函数模板是非法的.
在下面的示例中的模板函数中,在我看来,这种情况发生.即,两个模板函数onlyForDerivedObjects(...)
似乎(对我来说)仅由它们的默认模板参数不同.我意识到我在这里遗漏了一些东西,希望有人可以向我解释这一点,或者指出我可能会为自己找到顿悟的方向.
typename std::enable_if ...
当我认为它产生两个模板函数的情况时,我在下面的模板函数中错误分类了部分,这两个模板函数的区别仅在于它们的默认模板参数?基础和派生类:
class BaseA
{
public:
int getInt() const { return 21; };
};
class DerivedA : public BaseA {};
class BaseB
{
public:
int getAnotherInt() const { return 33; };
};
class DerivedB : public BaseB {};
Run Code Online (Sandbox Code Playgroud)
具有以下模板功能
/* template functions that, seemingly, only differ in their
default template arguments? */
template< class T,
typename std::enable_if<std::is_base_of<BaseA, …
Run Code Online (Sandbox Code Playgroud) (当我准备并几乎写完问题时,重新阅读相应的语言指南部分为我解答了,但可能Q&A可能对其他人有用,所以我会发布它)
背景
请考虑以下enum
情况,其中包含两种不同类型的关联值之一,Int
或者String
:
enum Foo {
case bar(Int)
case baz(Int)
case bax(Int)
case fox(String)
}
Run Code Online (Sandbox Code Playgroud)
在switch
语句中执行模式匹配时,我们可以构造复合案例,每个案例都包含几种可能的匹配模式(case
如果任何模式匹配则进入分支):
func foo(_ foo: Foo) -> Int {
switch foo {
case .bar, .baz, .bax: return 42
case .fox: return 0
}
}
Run Code Online (Sandbox Code Playgroud)
就像非复合案例一样,复合案例也可能包含价值绑定:
func foo(_ foo: Foo) -> Int {
switch foo {
case .bar(let x), .baz(let x), .bax(let x): return x
case .fox(let y): return Int(y) ?? 0
}
}
// or
func …
Run Code Online (Sandbox Code Playgroud) 我想用一个类方法实现一个协议,该方法将实现类的数组作为参数.例如这样的事情:
protocol MyProtocol {
static func foo(verticies: [Self]) -> Int
}
class MyClass : MyProtocol {
class func foo(verticies: [MyClass]) -> Int {
return 42
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试这个时,我收到以下错误:
协议'MyProtocol'要求'foo()'不能被非最终'MyClass'类满足,因为它在非参数非结果类型中使用'Self'
但是如果我使用MyClass类型的对象而不是数组,这可以很好地工作:
protocol MyProtocol {
static func foo(verticies: Self) -> Int
}
class MyClass : MyProtocol {
class func foo(verticies: MyClass) -> Int {
return 42
}
}
Run Code Online (Sandbox Code Playgroud)
为什么这不适用于数组类型,并且有正确的方法吗?
我需要静态地断言该类型的非constexpr数据成员的编译时大小std::array
,比方说arr_
,一个的非模板类是等于给定的(外部提供的)恒定。静态断言将从类内部完成,这意味着arr_
可以访问,但我不能依赖任何存储的常量(也不是非类型模板参数)的大小。即,断言需要完全依赖于arr_
数据成员的“一些检查” 。
如果constexpr
std::array<>::size()
/std::array<>::max_size()
是静态成员函数(decltype(arr_)::size()
/ decltype(arr_)::max_size()
)而不是非静态成员函数,我基本上会完成。
我有一种在成员的指向数据成员的指针上使用函数模板参数推导的工作方法arr_
,但我想知道是否有更简单/更整洁的方法。
#include <array>
#include <cstddef>
// Defined/provided from elsewhere.
constexpr std::size_t kArraySize = 12U;
constexpr std::size_t kAnotherArraySize = 12U;
template <typename T, typename U, std::size_t N>
constexpr std::size_t size_of_data_member_array(std::array<T, N> U::*) {
return N;
}
class Foo {
std::array<int, kArraySize> arr_;
static_assert(size_of_data_member_array(&Foo::arr_) == kAnotherArraySize, "");
};
int main() {}
Run Code Online (Sandbox Code Playgroud) G++ 和 Clang++ 同意以下代码段不是有效的 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 …
Run Code Online (Sandbox Code Playgroud) c++ language-lawyer explicit-instantiation c++-concepts c++20
考虑一个模板化实体,比如说(A)一个函数模板,和(B)一个类模板的成员枚举。
// (A)
template<auto>
int f();
// (B)
template <auto>
struct T { enum class E; };
Run Code Online (Sandbox Code Playgroud)
由于此类模板实体的相同显式专业化的重复定义,是否需要实现来诊断 ODR 违规?或者,换句话说,[basic.def.odr]/1 是否适用于显式专业化?
例如,GCC 和 Clang 都将以下程序诊断为格式错误:
// Single translation unit;
// primary template of 'f' declared as in (A) above.
template<>
int f<0>() { return 0; }
template<>
int f<0>() { return 1; }
// GCC & Clang - error: redefinition of 'int f() [with auto <anonymous> = 0]'
Run Code Online (Sandbox Code Playgroud)
而只有 Clang 将以下程序诊断为格式错误,而 GCC 接受它:
// Single translation unit;
// …
Run Code Online (Sandbox Code Playgroud) c++ templates one-definition-rule template-specialization language-lawyer