c++ quiz
#include <string>
#include <iostream>
using namespace std;
#define FMT_EXPAND(args) args
#define FMT_CONCAT(a, b) a##b
#define FMT_ADD_ARG_NAME(type, index) type arg##index
#define FMT_GET_ARG_NAME(type, index) arg##index
#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__))
#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define FMT_FOR_EACH1(f, x0) f(x0, 0)
#define FMT_FOR_EACH2(f, x0, x1) \
FMT_FOR_EACH1(f, x0), f(x1, 1)
#define FMT_FOR_EACH3(f, x0, x1, x2) \
FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2)
#define FMT_FOR_EACH4(f, x0, x1, x2, x3) \
FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3)
#define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \
FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4)
#define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \
FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5)
#define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \
FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6)
#define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \
FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7)
#define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \
FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8)
#define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \
FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
#define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N())
#define FMT_FOR_EACH(f, ...) \
FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__))
#define FMT_FOR_EACH_(N, f, ...) \
FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
#define FMT_VARIADIC_(ReturnType, func, call, ...) \
template <typename... Args> \
ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
const Args & ... args) { \
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__) \
); \
}
#define FMT_VARIADIC(ReturnType, func, ...) \
FMT_VARIADIC_(ReturnType, func, return func, __VA_ARGS__)
/*
FMT_FOR_EACH3(FMT_ADD_ARG_NAME, x0, x1, x2)
FMT_FOR_EACH2(FMT_ADD_ARG_NAME, x0 ,x1), FMT_ADD_ARG_NAME(x2, 2)
FMT_FOR_EACH1(FMT_ADD_ARG_NAME, x0), FMT_ADD_ARG_NAME(x1, 1), FMT_ADD_ARG_NAME(x2, 2)
FMT_ADD_ARG_NAME(x0, 0), FMT_ADD_ARG_NAME(x1, 1), FMT_ADD_ARG_NAME(x2, 2)
x0 arg0, x1 arg1, x2 arg2
FMT_FOR_EACH3(FMT_GET_ARG_NAME, x0, x1, x2)
FMT_GET_ARG_NAME(x0, 0), FMT_GET_ARG_NAME(x1, 1), FMT_GET_ARG_NAME(x2, 2)
arg0, arg1, arg2
*/
#include <string>
using namespace std;
FMT_VARIADIC(std::string, format, int, long, char)
template<typename... Args>
void print2(int int0, long long1, char char2, const Args & ...args)
{
return print2(int0, long1, char2);
}
void print2(int a, long b, char c)
{
std::cout<< "hello world"<<std::endl;
}
#include <tuple>
#include <type_traits>
using namespace std;
int main()
{
auto tuple = std::make_tuple(1,'B', 'A', "test");
std::cout << std::get<0>(tuple) << std::endl;
std::cout << std::get<1>(tuple) << std::endl;
std::cout << std::get<2>(tuple) << std::endl;
std::cout << std::get<3>(tuple) << std::endl;
std::cout << std::get<const char*>(tuple) << std::endl;
std::cout << std::get<int>(tuple) << std::endl;
std::cout << std::get<const char*>(tuple) << std::endl;
std::cout << std::get<char>(tuple) << std::endl;
/*
// 下面是C++14的特性
std::cout << std::get<int>(tuple) << std::endl;
std::cout << std::get<char>(tuple) << std::endl;
std::cout << std::get<const char*>(tuple) << std::endl;
*/
return 0;
}
/*******************************************/
namespace helpers
{
template<class T, class Tuple>
struct can_get_type:std::false_type{};
template<class T, class...Ts>
struct can_get_type<T,std::tuple<Ts...>>:
std::integral_constant<bool, (std::is_same<T,Ts>::value+...)==1>
{};
}
template<class T,class Tuple>
using can_get_type=typename helpers::can_get_type<T,Tuple>::type;
template <class T, class Tuple, std::enable_if_t<can_get_type<T,Tuple>{},int> =0>
decltype(auto) foo(Tuple &c)
{
std::cout<<"here"<<std::endl;
return std::get<T>(c);
}
/*
template <class T, class C>
auto foo(C &c) -> decltype(std::get<T>(c))
{
return std::get<T>(c);
}
*/
template <class>
void foo(...)
{
std::cout<<"...."<<std::endl;
}
int main2()
{
std::tuple<int> tuple{4};
foo<int>(tuple); // Works fine
foo<double>(tuple); // Crashes and burns
return 0;
}