【发布时间】:2020-03-17 03:25:06
【问题描述】:
尝试根据数组大小的有效性进行专门化:
// base template
template<int p, typename T = void>
struct absolute {
operator int () const { return 0; }
};
// positive case template
template<int p>
struct absolute<p, typename std::void_t<int[p]>> {
operator int () const { return p; }
};
// negative case template
template<int p>
struct absolute<p, typename std::void_t<int[-p]>> {
operator int () const { return -p; }
};
int main() {
std::cout << absolute<5>() << std::endl;
std::cout << absolute<-5>() << std::endl;
std::cout << absolute<0>() << std::endl;
}
问题 #1:
以上代码works nicely with gcc but fails to compile with clang。
Clang 生成错误:redefinition of template struct 'absolute'
谁是对的?
问题 #2:
Both with gcc and with clang(如果我们移除负面专业化以将 clang 带回游戏),不清楚为什么 absolute<0>() 选择基本模板。 There is nothing wrong 和 int[0] 以及 std::void_t<int[0]> 似乎更专业:
// base template
template<int p, typename T = void>
struct absolute {
operator int () const { return -1; }
};
// positive case template
template<int p>
struct absolute<p, typename std::void_t<int[p]>> {
operator int () const { return p; }
};
int main() {
std::cout << absolute<5>() << std::endl; // 5
std::cout << absolute<0>() << std::endl; // -1, why not 0?
}
并且...如果基本模板只是声明而没有实现,则为:
// base template
template<int p, typename T = void>
struct absolute;
Both gcc and clang would fail to compile,抱怨 不完整类型的无效使用:absolute<0>()。尽管它似乎适合特殊情况。
这是为什么呢?
【问题讨论】:
-
template<int p> struct absolute<p, typename std::void_t<int[p]>>和template<int p> struct absolute不是重复的吗? -
int[0]被 ISO C++ 标准禁止 timsong-cpp.github.io/cppwp/n4659/dcl.array#1 "其值应大于零" -
@L.F.所以这里不会失败:godbolt.org/z/sfSxam 是 clang 和 gcc 的错误?
-
@AmirKirsh 你忘了禁用扩展。 godbolt.org/z/RB96uc
-
也在 MSVC 中编译。
标签: c++ template-specialization