title: Can I hide implementation details of this concept from the end user?
body: <p>I have looked at several similar questions on SO. Maybe I am not grokking the solutions there. In those questions when the return type is <code>auto</code> or templated then separating declaration and definition in two different units causes a failure in compilation. This can be solved by explicitly declaring a concrete signature for the function definition. In my case I am not sure how to do that.</p>
  <p>My scenario is as below:</p>
  <pre><code>// api.h
  template &lt;typename TImpl&gt;
  concept IsAProcessor = requires(TImpl impl)
  {
      impl.init();
      impl.process();
      impl.deinit();
  };
  
  
  enum UseCase {
      USECASE1,
      USECASE2
  };
  
  template &lt;IsAProcessor TImpl&gt;
  void Process(TImpl&amp; impl)
  {
      impl.process();
  }
  
  class Engine
  {
  public:
      IsAProcessor auto getInstance(UseCase a);
  };
  // End - api.h
  
  // api.cpp
  #include &quot;api.h&quot;
  #include &quot;third_party.h&quot;
  IsAProcessor auto Engine::getInstance(UseCase a) {
      switch (UseCase) {
          case USECASE1:
              return UseCase1Impl(); // Defined in third_party.h and satisfies concept requirement.
          case USECASE2:
              return UseCase2Impl();
      }
  
      
  }
  // End - api.cpp
  
  // third_party.h
  class UseCase1Impl {
  public:
      void init(void);
      void process(void);
      void deinit(void);
  }
  // End - third_party.h
  
  // third_party.cpp
  #include &quot;third_party.h&quot;
  void UseCase1Impl::init(void) {...};
  // and so forth
  // End - third_party.cpp
  
  // User code
  #include &quot;api.h&quot;
  
  {
      auto en = Engine();
      auto usecase = en.getInstance(UseCase::USECASE1);
      //^^^ cannot be used before it is defined here    
      Process(usecase);
  }
  </code></pre>
  <p>As I mentioned in the question, it is not desirable to expose UseCase1Impl and UseCase2Impl. How do I get past the error: <code>function 'getInstance' with deduced return type cannot be used before it is defined</code></p>