繁体   English   中英

具有非类型模板参数的功能模板中的static_assert

[英]static_assert in function template with non-type template parameter

我有一个带有整数模板参数的函数模板。 我只想提供特定整数的实现。 尝试将函数模板与其他参数一起使用会导致编译错误。

我以下面介绍的方式使用了static_assert

#include <type_traits>
#include <iostream>

template <typename T>
struct false_type : public std::false_type {};

template <int T>
void function() {
    static_assert(false_type<decltype(T)>::value, "Error");
};

template <>
void function<1>() {
    std::cout << 1 << std::endl;
}

int main() {
    function<1>();
}

该代码在gcc 9.1给出error: static assertion failed之前一直运行良好error: static assertion failed

我想知道是否有一种技术可以实现我的目标并且与gcc 9.1兼容?

即使在从未实例化的模板中,其第一个参数是不相关的虚假常量的static_assert始终“ static_assert错误,无需诊断”。 (因此,g ++和clang ++都不是“不正确的”。)在您的函数模板中, T依赖于值,但不依赖于类型(其类型始终为int ),因此decltype(T)不依赖于, false_type<int>::value

false_type只将false_type也接受一个int作为参数?

#include <type_traits>
#include <iostream>

template <int>
struct false_type : public std::false_type {};

template <int T>
void function() {
    static_assert(false_type<T>::value, "Error");
};

template <>
void function<1>() {
    std::cout << 1 << std::endl;
}

int main() {
     function<1>();
}

GCC 9.1似乎认识到false_type<decltype(T)>::value实际上并不依赖于T ,这使它可以及早评估条件(第一次看到模板false_type<decltype(T)>::value不是实例化时)。

这是一种解决方法:

template <auto V, auto...> inline constexpr auto dependent_value = V;

template <int T>
void function()
{
    static_assert(dependent_value<false, T>, "Error");
}

这样,编译器必须实例化function<T>来评估dependent_value<false, T> (因为在定义function<T> 之后 ,可以对dependent_value进行专门化处理)。


请注意,由于无法为function<int T>实现生成有效的实例化,因此问题中的代码格式不正确,不需要进行诊断

此解决方法没有此问题,因为您可以通过先专门化dependent_valuefunction<int T>进行有效实例化。


还有一个不涉及static_assert的简单解决方案:

template <int T> void function() = delete;

当我第一次回答这个问题时,我不明白原始代码是什么问题,但是现在,由于其他受访者的支持,我做到了,所以这一切都值得。

无论如何,一个显而易见的解决方案是将三个模板替换为:

template <int T>
void function() {
    static_assert(T == 1, "Error");
};

在gcc可以正常工作

顺便说一下,clang和MSVC仍然可以成功地编译原始代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM