mirror of
https://github.com/bspeice/speice.io
synced 2024-12-22 16:48:10 -05:00
Add noexcept
and volatile
This commit is contained in:
parent
cc5ca25fa5
commit
fb29d8c9da
@ -14,13 +14,15 @@ useful because both languages are "system."
|
|||||||
Worth noting differences in goals: polymorphism in C++ is only duck typing. Means that static
|
Worth noting differences in goals: polymorphism in C++ is only duck typing. Means that static
|
||||||
polymorphism happens separate from visibility, overloading, etc.
|
polymorphism happens separate from visibility, overloading, etc.
|
||||||
|
|
||||||
Rust's trait system is different (need a better way to explain that) which allows for trait markers,
|
Rust's trait system is more thorough (need a better way to explain that), which allows for trait
|
||||||
auto-deriving, arbitrary self.
|
markers, auto-deriving, arbitrary self.
|
||||||
|
|
||||||
# Simple Example
|
# Simple Example
|
||||||
|
|
||||||
Accept parameter types, return known type. Also needs to be generic over parameter types.
|
Accept parameter types, return known type. Also needs to be generic over parameter types.
|
||||||
|
|
||||||
|
Should make a quick note that C++ doesn't allow
|
||||||
|
|
||||||
# Generic return
|
# Generic return
|
||||||
|
|
||||||
Same name and parameter signature, but return different types - `AsRef`
|
Same name and parameter signature, but return different types - `AsRef`
|
||||||
@ -113,7 +115,7 @@ public:
|
|||||||
|
|
||||||
# Method Qualifiers
|
# Method Qualifiers
|
||||||
|
|
||||||
Rust allows declaring immutable, mutable, and consumed arguments (including `self`).
|
Rust allows declaring immutable or mutable.
|
||||||
|
|
||||||
C++ can use `const_cast` to assert "constness" of `this`:
|
C++ can use `const_cast` to assert "constness" of `this`:
|
||||||
|
|
||||||
@ -254,11 +256,174 @@ int main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Rust is much simpler about all this - the signature for a trait implementation must _exactly_ match
|
Rust is much simpler about all this - the signature for a trait implementation must _exactly_ match
|
||||||
a trait definition.
|
a trait definition. Actual usage rules may be weird (what happens with a mut reference
|
||||||
|
`#[derive(Copy)]` struct when a function takes immutable by value?), but the polymorphic side stays
|
||||||
|
consistent.
|
||||||
|
|
||||||
C++ also has way more qualifiers - `noexcept`, `override`, `volatile`, but I can't find a way to
|
Can also use `noexcept` qualifier. Not sure why this has issues:
|
||||||
require those qualifiers being present. In contrast Rust doesn't have exceptions, doesn't have
|
|
||||||
inheritance, and uses `unsafe` to handle `volatile`, so doesn't need to care about these qualifiers.
|
```c++
|
||||||
|
#include <concepts>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept NoExceptMethod = requires (T a) {
|
||||||
|
{ noexcept(a.method()) } -> std::same_as<std::uint64_t>;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NoExcept {
|
||||||
|
public:
|
||||||
|
std::uint64_t method() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void f(NoExceptMethod auto a) {}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
NoExcept x{};
|
||||||
|
|
||||||
|
f(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or why this is allowable:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include <concepts>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept NoExceptMethod = requires (T a) {
|
||||||
|
{ a.method() } -> std::same_as<std::uint64_t>;
|
||||||
|
noexcept(a.method());
|
||||||
|
};
|
||||||
|
|
||||||
|
class NoExcept {
|
||||||
|
public:
|
||||||
|
std::uint64_t method() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void f(NoExceptMethod auto a) {}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
NoExcept x{};
|
||||||
|
|
||||||
|
f(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Turns out this is the way to do it:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include <concepts>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept NoExceptMethod = requires (T a) {
|
||||||
|
{ a.method() } noexcept -> std::same_as<std::uint64_t>;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NoExcept {
|
||||||
|
public:
|
||||||
|
std::uint64_t method() noexcept {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void f(NoExceptMethod auto a) {}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
NoExcept x{};
|
||||||
|
|
||||||
|
f(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
But this doesn't compile?
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include <concepts>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept NoExceptMethod = requires (T a) {
|
||||||
|
// Note that we simply replaced `noexcept` with `const`
|
||||||
|
{ a.method() } const -> std::same_as<std::uint64_t>;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NoExcept {
|
||||||
|
public:
|
||||||
|
// Note that we simply replaced `noexcept` with `const`
|
||||||
|
std::uint64_t method() const {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void f(NoExceptMethod auto a) {}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
NoExcept x{};
|
||||||
|
|
||||||
|
f(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
<source>:6:19: error: expected ';' before 'const'
|
||||||
|
6 | { a.method() } const -> std::same_as<std::uint64_t>;
|
||||||
|
| ^~~~~~
|
||||||
|
| ;
|
||||||
|
```
|
||||||
|
|
||||||
|
In general: exceptions add an orthogonal dimension of complexity on top of `const` because of how
|
||||||
|
difficult it is to deduce `noexcept` in practice. See also
|
||||||
|
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1667r0.html
|
||||||
|
|
||||||
|
Also, concepts getting so hard to understand that we write test cases:
|
||||||
|
https://andreasfertig.blog/2020/08/cpp20-concepts-testing-constrained-functions/
|
||||||
|
|
||||||
|
And for handling `volatile`:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include <concepts>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept VolatileMethod = requires(volatile T a) {
|
||||||
|
{ a.method() } -> std::same_as<std::uint64_t>;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Volatile {
|
||||||
|
public:
|
||||||
|
std::uint64_t method() volatile {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void f(VolatileMethod auto a) {
|
||||||
|
a.method();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Volatile x{};
|
||||||
|
|
||||||
|
f(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Though the compiler nicely warns us that we shouldn't do this:
|
||||||
|
|
||||||
|
```text
|
||||||
|
<source>:5:46: warning: 'volatile'-qualified parameter is deprecated [-Wvolatile]
|
||||||
|
5 | concept VolatileMethod = requires(volatile T a) {
|
||||||
|
| ~~~~~~~~~~~^
|
||||||
|
```
|
||||||
|
|
||||||
|
C++ also has `override`, but doesn't make much sense to impose that as a requirement; inheritance
|
||||||
|
and concepts are orthogonal systems.
|
||||||
|
|
||||||
# Implement methods on remote types
|
# Implement methods on remote types
|
||||||
|
|
||||||
@ -401,6 +566,13 @@ error message for `decltype()` is actually much nicer than the `static_assert`..
|
|||||||
[type traits](http://en.cppreference.com/w/cpp/experimental/is_detected) to fix those issues, but
|
[type traits](http://en.cppreference.com/w/cpp/experimental/is_detected) to fix those issues, but
|
||||||
mostly please just use concepts.
|
mostly please just use concepts.
|
||||||
|
|
||||||
|
# Templated splatter
|
||||||
|
|
||||||
|
Rust can't handle arbitrary numbers of template parameters. Can use macros, but I should investigate
|
||||||
|
`typename...` types.
|
||||||
|
|
||||||
|
Common pattern to implement
|
||||||
|
|
||||||
# Potentially excluded
|
# Potentially excluded
|
||||||
|
|
||||||
Some ideas related to traits, but that I'm not sure sufficiently fit the theme. May be worth
|
Some ideas related to traits, but that I'm not sure sufficiently fit the theme. May be worth
|
||||||
|
Loading…
Reference in New Issue
Block a user