Skip to content

Instantly share code, notes, and snippets.

// This alias template is declared outside of S2 so that 'S1' won't be changed into a base class symbol
template<int i> using S1_alias = typename S1::S0<i>::type;
struct S2 : S1
{
// There is regression that prevents the type replacement from happening when there is a base class symbol
// A base class symbol for 'S1' is injected into the qualified name by the compiler
//template<int i> void f(typename S0<i>::type);
// 'S1' is changed to a base class symbol for 'S1'
//template<int i> void f(typename S1::S0<i>::type);
// cl bug.cpp /clr /LD
template<int> struct S {};
#define FUN0(i) static void ToNative(S<i>) {}
#define FUN1(i) FUN0((i) * 2 + 0)FUN0((i) * 2 + 1)
#define FUN2(i) FUN1((i) * 2 + 0)FUN1((i) * 2 + 1)
#define FUN3(i) FUN2((i) * 2 + 0)FUN2((i) * 2 + 1)
#define FUN4(i) FUN3((i) * 2 + 0)FUN3((i) * 2 + 1)
#define FUN5(i) FUN4((i) * 2 + 0)FUN4((i) * 2 + 1)
#include <type_traits>
namespace detail
{
struct any
{
template<class T>
any(T &&);
};
#include <iostream>
#include <type_traits>
template<typename T, int N>
struct S1 {
// A somewhat 'expensive' ctor
template<typename U, typename = std::enable_if_t<std::is_arithmetic<std::decay_t<U>>::value>>
S1(U);
float operator()() const;