问题是我在 Nicolai M. Josuttis 的一本名为
C++17 Complete Guide
的书中遇到了一段代码,第 122 页。该代码片段对我不起作用。我想知道为什么。
template<auto V1, decltype(V1)... VS>
class HomoValueList {
};
作者声称这样的声明应该禁止非同构模板参数。但实际上我不能产生错误:
int main() {
HomoValueList<1, 'a', true> vals4; // Must be an error according to the author but not for me.
return 0;
}
这段代码是因为隐式转换而编译的,所以这本书是错误的。
我想知道自 C++17 标准发布以来是否发生了一些变化,因为作者声称必须禁止该行。
我不这么认为。即使在 C++17 模式下,最新的 Clang、GCC 和 MSVC 都接受此代码。
这是一个可行的 C++20 替代方案:(感谢 @PatrickRoberts)
template <auto V1, auto ...VS>
requires (std::is_same_v<decltype(V1), decltype(VS)> && ...)
class HomoValueList
{};
C++20 之前的版本,您可以使用
static_assert
,但请注意,它不适合 SFINAE。
template<auto V1, auto ...VS>
class HomoValueList
{
static_assert((std::is_same_v<decltype(V1), decltype(VS)> && ...));
};