Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6943159
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T13:07:12+00:00 2026-05-27T13:07:12+00:00

Follow-up question to [Does casting to a pointer to a template instantiate that template?]

  • 0

Follow-up question to [Does casting to a pointer to a template instantiate that template?].

The question is just as the title says, with the rest of the question being constraints and usage examples of the class template, aswell as my tries to achieve the goal.

An important constraint: The user instantiates the template by subclassing my class template (and not through explicitly instantiating it like in my tries below). As such, it is important to me that, if possible, the user doesn’t need to do any extra work. Just subclassing and it should work (the subclass actually registers itself in a dictionary already without the user doing anything other than subclassing an additional class template with CRTP and the subclass is never directly used by the user who created it). I am willing to accept answers where the user needs to do extra work however (like deriving from an additional base), if there really is no other way.


A code snippet to explain how the class template is going to be used:

// the class template in question
template<class Resource>
struct loader
{
  typedef Resource res_type;
  virtual res_type load(std::string const& path) const = 0;
  virtual void unload(res_type const& res) const = 0;
};

template<class Resource, class Derived>
struct implement_loader
  : loader<Resource>
  , auto_register_in_dict<Derived>
{
};

template<class Resource>
Resource load(std::string const& path){
  // error should be triggered here
  check_loader_instantiated_with<Resource>();

  // search through resource cache
  // ...

  // if not yet loaded, load from disk
  // loader_dict is a mapping from strings (the file extension) to loader pointers
  auto loader_dict = get_all_loaders_for<Resource>();
  auto loader_it = loader_dict.find(get_extension(path))
  if(loader_it != loader_dict.end())
    return (*loader_it)->load(path);
  // if not found, throw some exception saying that
  // no loader for that specific file extension was found
}

// the above code comes from my library, the code below is from the user

struct some_loader
  : the_lib::implement_loader<my_fancy_struct, some_loader>
{
  // to be called during registration of the loader
  static std::string extension(){ return "mfs"; }
  // override the functions and load the resource
};

And now in tabular form:

  • User calls the_lib::load<my_fancy_struct> with a resource path
  • Inside the_lib::load<my_fancy_struct>, if the resource identified by the path isn’t cached already, I load it from disk
  • The specific loader to be used in this case is created at startup time and saved in a dictionary
  • There is a dictionary for every resource type, and they map [file extension -> loader pointer]
  • If the dictionary is empty, the user either
    • didn’t create a loader for that specific extension or
    • didn’t create a loader for that specific resource
  • I only want the first case to have me throw a runtime exception
  • The second case should be detected at compile / link time, since it involves templates

Rationale: I’m heavily in favor of early errors and if possible I want to detect as many errors as possible before runtime, i.e. at compile and link time. Since checking if a loader for that resource exists would only involve templates, I hope it’s possible to do this.


The goal in my tries: Trigger a linker error on the call to check_error<char>.

// invoke with -std=c++0x on Clang and GCC, MSVC10+ already does this implicitly
#include <type_traits>

// the second parameter is for overload resolution in the first test
// literal '0' converts to as well to 'void*' as to 'foo<T>*'
// but it converts better to 'int' than to 'long'
template<class T>
void check_error(void*, long = 0);

template<class T>
struct foo{
  template<class U>
  friend typename std::enable_if<
    std::is_same<T,U>::value
  >::type check_error(foo<T>*, int = 0){}
};

template struct foo<int>;

void test();

int main(){ test(); }

Given the above code, the following test definition does achieve the goal for MSVC, GCC 4.4.5 and GCC 4.5.1:

void test(){
  check_error<int>(0, 0); // no linker error
  check_error<char>(0, 0); // linker error for this call
}

However, it should not do that, as passing a null pointer does not trigger ADL. Why is ADL needed? Because the standard says so:

§7.3.1.2 [namespace.memdef] p3

[…] If a friend declaration in a nonlocal class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup or by qualified lookup until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship). […]

Triggering ADL through a cast, as in the following definition of test, achieves the goal on Clang 3.1 and GCC 4.4.5, but GCC 4.5.1 already links fine, as does MSVC10:

void test(){
  check_error<int>((foo<int>*)0);
  check_error<char>((foo<char>*)0);
}

Sadly, GCC 4.5.1 and MSVC10 have the correct behaviour here, as discussed in the linked question and specifically this answer.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T13:07:12+00:00Added an answer on May 27, 2026 at 1:07 pm

    After thinking a bit about your problem, I don’t see any way to achieve this. You need a way to make the instantiation “export” something outside the template so that it can be accessed without referencing the instantiation. A friend function with ADL was a good idea, but unfortunately it was shown that for ADL to work, the template had to be instantiated. I tried to find another way to “export” something from the template, but failed to find one.

    The usual solution to your problem is to have the user specializes a trait class:

    template < typename Resource >
    struct has_loader : boost::mpl::false_ {};
    
    template <>
    struct has_loader< my_fancy_struct > : boost::mpl::true_ {};
    

    To hide this from the user, you could provide a macro:

    #define LOADER( loaderName, resource ) \
    template <> struct has_loader< resource > : boost::mpl::true_ {}; \
    class loaderName \
      : the_lib::loader< resource > \
      , the_lib::auto_register_in_dict< loaderName >
    
    LOADER( some_loader, my_fancy_struct )
    {
      public:
        my_fancy_struct load( std::string const & path );
    };
    

    It is up to you to determine whether having this macro is acceptable or not.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

edit #2: Question solved halfways. Look below As a follow-up question, does anyone know
Follow up question from Multi-core usage, threads, thread-pools . Are threads moved from one
This is a follow up question to that at Can I create a HTML
This is a follow up question due to changes being made to the OP
Follow-up question to this question : (note that this is not a duplicate, I'm
Follow-up question to this one . Basically, in the following code, why does the
This is a follow on question to How do I delete 1 file from
This is a follow-on question to the How do you use ssh in a
This is a follow up question to This Question . I like (and understand)
This is a follow up question . So, Java store's integers in two's-complements and

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.