0

Context: I am playing around with writing expression templates and C++11 features. The attached code sample is just an experament for fun. In this variation of ETs, each expression keeps track of its own return type. common_type is then used by the compiler to find what the return types of other expressions would be based on the sub-expression return types.

Problem: You can see the complete example here

I have a set of functions that dynamically figure out the return type using common_type like so:

template
    <
        typename... Args2,
        typename T1,
        template < typename... > class T2
    >
    Binary
    <
        T1,
        T2< Args2... >,
        typename common_type< T1 , typename select_last< Args2... >::type >::type
    > const
    operator*(T1 u, T2< Args2... > v)
{
    cout << "Operator (value, expr)" << endl;
    return Binary
    <
        T1,
        T2< Args2... >,
        typename common_type< T1 , typename select_last< Args2... >::type >::type
    >(u, v);
}

When compiled with clang++ -std=c++11 -O3 -Wall -pedantic -Wextra main.cpp -lboost_iostreams -lz everything works fine. When compiled with clang++ -stdlib=libc++ -std=c++11 -O3 -Wall -pedantic -Wextra main.cpp -lcxxrt -ldl -lboost_iostreams -lz I get build errors where non-primitives are being passed in to common_type. (aka incompatible operand types ('Unary<int, int>' and 'int'))

Question: Is the wrong function being matched? It seems like common_type may be evaluated even in the functions not being used. Is there an easy way to delay the evaluation of common_type for the two terminal expression operators?

Cory
  • 151
  • 12
  • 4
    Perhaps common_type is not SFINAE friendly in libc++ yet. That was subject of [a proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3843.pdf). – Columbo May 22 '15 at 20:04
  • @Columbo That would make sense. Should I not worry about it since future versions will likely have it? I just want to make sure this code is fairly compiler-independent. – Cory May 22 '15 at 20:14
  • 1
    @Columbo Probably because the current specification is [rather broken](http://cplusplus.github.io/LWG/lwg-active.html#2465). – T.C. May 22 '15 at 20:32
  • @T.C. How is that affecting whether the trait is SFINAE-friendly? Did the libc++ devs just decide to not implement any kind of SFINAE-friendliness until that DR is sorted out? – Columbo May 22 '15 at 20:44
  • @Columbo Well, the C++14 specification is non-SFINAE-friendly, but otherwise works. And then you have a LWG issue that replaces it with something that's SFINAE-friendly but quite broken. We don't have a good, working, specification of what SFINAE-friendly `common_type` is supposed to do. Also, [this](http://libcxx.llvm.org/cxx1z_status.html) says that `common_type` is waiting on the resolution of that DR – T.C. May 22 '15 at 21:01
  • @T.C. I see. Should've researched that a bit more, sorry. – Columbo May 22 '15 at 21:13

0 Answers0