Ticket #6915: substitution_failure_test.cpp

File substitution_failure_test.cpp, 1.8 KB (added by ulidtko@…, 10 years ago)

reproducing example

Line 
1#include <iostream>
2
3//#define BOOST_RESULT_OF_USE_DECLTYPE 1
4
5#include <boost/fusion/container.hpp>
6#include <boost/fusion/support.hpp>
7#include <boost/fusion/functional.hpp>
8
9
10template<typename T> struct subst_failure_if_not_int {};
11template<> struct subst_failure_if_not_int<int> { typedef int type; };
12
13template<typename T>
14typename subst_failure_if_not_int<T>::type
15dispatch_int(int) {
16 /* this overload is eliminated when substitution failure occurs */
17 std::cout << "called int version\n";
18 return 0;
19}
20
21template<typename T>
22void
23dispatch_int(long) {
24 /* this is fallback overload */
25 std::cout << "called default version\n";
26}
27
28void test1() {
29 dispatch_int<int> (0); // prints "called int version"
30 dispatch_int<float> (0); // prints "called default version"
31}
32
33
34/* now, exactly the same approach applied to boost::fusion::invoke */
35
36struct F {
37 template<class> struct result {};
38 template<class F> struct result<F(float)> { typedef int type; };
39 int operator()(float) { std::cout << "invoked F(float)\n"; }
40};
41
42
43template<class F, class Sequence>
44typename boost::fusion::result_of::invoke<F, Sequence>::type
45try_invoke(int) {
46 std::cout << "called invoke()-ing overload\n";
47 return boost::fusion::invoke(F(), Sequence());
48}
49
50template<class F, class Sequence>
51void
52try_invoke(long) {
53 std::cout << "called fallback overload\n";
54}
55
56struct junk { int i; };
57
58void test2() {
59 // fails to compile under MSVC 9,
60 // compiles and works as intended under GCC 4.6 when BOOST_RESULT_OF_USE_DECLTYPE enabled,
61 // fails to compile under GCC 4.6 with decltype() usage disabled:
62 try_invoke<F, boost::fusion::vector<float>> (0);
63
64 // fails to compile in all tested cases, while should be selecting fallback overload:
65 try_invoke<F, boost::fusion::vector<junk>> (0);
66}
67
68
69int main() {
70 test1();
71 test2();
72}
73