Skip to content

pcg64 can't be printed #19

@ahh

Description

@ahh

Here's an example that won't build for pcg_t = ::pcg64 but works for pcg_t = ::pcg32.

#include <random>
#include <sstream>

#include "third_party/pcg_random/include/pcg_random.hpp"

namespace {
  using pcg_t = ::pcg64;
}

int main()
{
  pcg_t rng(std::random_device{}());

  std::stringstream out;
  out << rng;

  return 0;
}

I can verify similar issues in pcg-test.cpp if you add prints to std::cout or reads from std::cin.

What I believe is happening is: you're relying on Koenig lookup to find the definitions of operator<< and operator>> in namespace pcg_extras. But pcg128_t is typically a typedef for __uint128_t; Koenig lookup doesn't work on typedefs (or more precisely, looks at the resolved type's namespace, not the typedef's.)

As I see it there are three possible fixes:

  1. Move the operator definitions to the global namespace -- this is a bad idea, for one thing because anyone could have a conflicting definition.

  2. Add a wrapper class around the typedef. This would solve the namespacing issue neatly; I don't know if we'd incur runtime cost from the compiler choking on the wrapper. Hopefully not but hard to prove.

  3. Replace the operator<< for pcg128_t with similar free functions named (say) Input and Output and use SFINAE in the definitions of the engine operator<< to prefer those if available. A bit clunky, but would work. (Also sort of necessary for the uint8_t stuff, I think.)

I'm hacking together 3) to see how bad it looks, but not done yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions