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

  • Home
  • SEARCH
  • 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 351695
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T11:40:04+00:00 2026-05-12T11:40:04+00:00

I want to do something like template <typename T> void foo(const T& t) {

  • 0

I want to do something like

template <typename T>
void foo(const T& t) {
   IF bar(t) would compile
      bar(t);
   ELSE
      baz(t);
}

I thought that something using enable_if would do the job here, splitting up foo into two pieces, but I can’t seem to work out the details. What’s the simplest way of achieving this?

  • 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-12T11:40:04+00:00Added an answer on May 12, 2026 at 11:40 am

    There are two lookups that are done for the name bar. One is the unqualified lookup at the definition context of foo. The other is argument dependent lookup at each instantiation context (but the result of the lookup at each instantiation context is not allowed to change behavior between two different instantiation contexts).

    To get the desired behavior, you could go and define a fallback function in a fallback namespace that returns some unique type

    namespace fallback {
      // sizeof > 1
      struct flag { char c[2]; };
      flag bar(...);
    }
    

    The bar function will be called if nothing else matches because the ellipsis has worst conversion cost. Now, include that candidates into your function by a using directive of fallback, so that fallback::bar is included as candidate into the call to bar.

    Now, to see whether a call to bar resolves to your function, you will call it, and check whether the return type is flag. The return type of an otherwise chosen function could be void, so you have to do some comma operator tricks to get around that.

    namespace fallback {
      int operator,(flag, flag);
    
      // map everything else to void
      template<typename T> 
      void operator,(flag, T const&);
    
      // sizeof 1
      char operator,(int, flag);
    }
    

    If our function was selected then the comma operator invocation will return a reference to int. If not or if the selected function returned void, then the invocation returns void in turn. Then the next invocation with flag as second argument will return a type that has sizeof 1 if our fallback was selected, and a sizeof greater 1 (the built-in comma operator will be used because void is in the mix) if something else was selected.

    We compare the sizeof and delegate to a struct.

    template<bool>
    struct foo_impl;
    
    /* bar available */
    template<>
    struct foo_impl<true> {
      template<typename T>
      static void foo(T const &t) {
        bar(t);
      }
    };
    
    /* bar not available */
    template<>
    struct foo_impl<false> {
      template<typename T>
      static void foo(T const&) {
        std::cout << "not available, calling baz...";
      }
    };
    
    template <typename T>
    void foo(const T& t) {
       using namespace fallback;
    
       foo_impl<sizeof (fallback::flag(), bar(t), fallback::flag()) != 1>
         ::foo(t);
    }
    

    This solution is ambiguous if the existing function has an ellipsis too. But that seems to be rather unlikely. Test using the fallback:

    struct C { };
    int main() {
      // => "not available, calling baz..."
      foo(C());
    }
    

    And if a candidate is found using argument dependent lookup

    struct C { };
    void bar(C) {
      std::cout << "called!";
    }
    int main() {
      // => "called!"
      foo(C());
    }
    

    To test unqualified lookup at definition context, let’s define the following function above foo_impl and foo (put the foo_impl template above foo, so they have both the same definition context)

    void bar(double d) {
      std::cout << "bar(double) called!";
    }
    
    // ... foo template ...
    
    int main() {
      // => "bar(double) called!"
      foo(12);
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

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.