非类型模板参数:如何传递对基类对象的引用?

JVD*_*JVD 6 c++

似乎不可能将对派生对象的基类对象的引用作为模板参数传递,正如我在这里尝试的那样:

struct a
{ int _v;
  constexpr a():_v(0){}
  constexpr a(int v): _v(v){} 
};

struct c: public a
{ constexpr c():a(){}
  constexpr c(int v):a(v){} 
};

extern const c default_a;

constexpr const c default_a { 1 };

const a& c_as_a = default_a;
//    ^-- this line (16) causes no error - c can be converted to a

template < const a & The_A = default_a >
struct b
{ constexpr static const a &the_a = The_A;
};

b<> a_b;

// Template instantiation causes error:
// t.C:24:7: error: could not convert template argument 'default_a' to 'const a&'
// b<> a_b;
//   ^
Run Code Online (Sandbox Code Playgroud)

我原本期望'c'对象'default_a',因为它来自'a',可以接受为'const a&',就像它在16行上一样.

为什么这不能作为模板参数?

规范的哪一部分实际上要求这种行为?

也许我的gcc-5.3.0版本有点缺陷?

有人找到了一个很好的解决方法/传递派生对象作为基类对象引用模板参数的方法吗?

我不能在模板参数列表中用'default_a'替换引用变量'c_as_a':

template < const a & The_A = c_as_a >
Run Code Online (Sandbox Code Playgroud)

tC:24:7:错误:'const a&c_as_a'不是类型'const a&'的有效模板参数,因为引用变量没有常量地址b <> a_b;

我也不能替换任何constexpr函数调用,它会执行以下操作:

 constexpr const a& c_as_a( const c &c ){ return *reinterpret_cast<const a*>(&c);}
 ...
 template < const a & The_A = c_as_a( default_a ) >
Run Code Online (Sandbox Code Playgroud)

因为这个调用不是"具有外部链接的对象".

任何建议如何实现传递对派生对象的基类的引用作为模板参数将非常感激 - 它必须是可能的,我只是看不到ATM如何.

必须有一种方法可以将对象的基类对象的引用指定为模板参数.

JVD*_*JVD 1

gcc 特定的解决方法:

struct a
{ int _v;
  constexpr a():_v(0){}
  constexpr a(int v): _v(v){} 
};

struct c: public a
{ constexpr c():a(){}
  constexpr c(int v):a(v){} 
};

extern const c _default_c;

constexpr const c _default_c { 1 };

extern const a default_a;

const a default_a __attribute__((alias("_default_c")));

template < const a & The_A = default_a >
struct b
{ constexpr static const a &the_a = The_A;
};

b<> a_b;
Run Code Online (Sandbox Code Playgroud)

以上编译OK。

令人高兴的是,我们知道“_default_c”的名称没有被破坏。