#include <iostream>
#include <typeinfo>
int* returnsPointer() { return nullptr; }
int& returnsRef() { static int a; return a; }
int returnsValue() { return 10; }
template<typename> void printType();
template<> void printType<int>()
{
std::cout << "int\n";
}
template<> void printType<int*>()
{
std::cout << "int*\n";
}
template<> void printType<int&>()
{
std::cout << "int&\n";
}
int main()
{
// similar D behavior in C++:
auto d_pointer = returnsPointer();
auto d_ref = returnsRef();
auto d_ref2 = &returnsRef();
auto d_value = returnsValue();
printType<decltype(d_pointer)>();
printType<decltype(d_ref)>();
printType<decltype(d_ref2)>();
printType<decltype(d_value)>();
std::cout << "--------------------\n";
// desired C++ behavior to have in D:
auto* c_pointer = returnsPointer();
// auto* c_ref = returnsRef(); // error can't compile this (desired behavior here)
auto* c_ref2 = &returnsRef();
// auto* c_value = returnsValue(); // error can't compile this
printType<decltype(c_pointer)>();
printType<decltype(c_ref2)>();
}