Skip to content

Instantly share code, notes, and snippets.

@xealits
Last active May 28, 2025 21:52
Show Gist options
  • Save xealits/560ad10cc39d58553de36630b19eb5ac to your computer and use it in GitHub Desktop.
Save xealits/560ad10cc39d58553de36630b19eb5ac to your computer and use it in GitHub Desktop.
Static duck typing in C++
#include <iostream>
#include <source_location>
#include <string>
struct Quack;
template <typename T>
concept Duck = requires(T t) {
{ t.quack() } -> std::convertible_to<Quack>;
// could be -> std::same_as<Quack>;
};
struct Quack {
std::string data;
};
template <typename T>
void print(const T &inp, const std::source_location &location =
std::source_location::current()) noexcept {
std::cout << location.function_name() << ", " << inp << '\n';
}
class Foo {
public:
Quack quack(void) {
Quack res;
res.data = "hey!";
return res;
}
};
class Bar {
static constexpr Quack _quack{.data = "static hey!"};
public:
static Quack quack(void) {
print(&_quack); // is it really constexpr if there is a pointer?
// a std::string has to be in memory
return _quack;
}
};
class Baz {
public:
static Quack quack(void) {
Quack res;
res.data = "Baz quack";
print(&res);
return res;
}
};
void checkDucks(Duck auto d) {
auto res = d.quack();
print(res.data);
}
int main() {
Foo f;
Bar b;
Baz z;
checkDucks(f);
b.quack();
checkDucks(b);
z.quack();
checkDucks(z);
return 0;
}
@xealits
Copy link
Author

xealits commented May 28, 2025

$ clang++ -std=c++23 -Wall -Wconversion duck_typing_static.cpp 
$ ./a.out 
void checkDucks(Duck auto) [d:auto = Foo], hey!
static Quack Bar::quack(), 0x5ca096e31d88
static Quack Bar::quack(), 0x5ca096e31d88
void checkDucks(Duck auto) [d:auto = Bar], static hey!
static Quack Baz::quack(), 0x7ffcaafe2d30
static Quack Baz::quack(), 0x7ffcaafe2ce8
void checkDucks(Duck auto) [d:auto = Baz], Baz quack

@xealits
Copy link
Author

xealits commented May 28, 2025

Blogs about requires and checking for the methods with { t.member() } -> std::convertible_to<...>:
https://akrzemi1.wordpress.com/2020/01/29/requires-expression/
https://www.sandordargo.com/blog/2021/03/17/write-your-own-cpp-concepts-part-ii

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment