当通过声明表达式调用时,static_assert应该可以工作
Is static_assert supposed to work when invoked via decltype expression?
我希望以static_assert
在最终行上检查以下代码失败。但是,在MSVC2015和GCC 6.2中,它可以成功编译。它确实无法按照Clang 3.9的预期进行编译。这是编译器错误还是static_assert
在decltype()
中不起作用?
#include <tuple>
#include <type_traits>
template<typename T>
struct Wrapper {};
template<typename T, typename U>
constexpr std::tuple<T, U> operator|(Wrapper<T>, Wrapper<U>)
{
static_assert(std::is_same<T,U>::value == false, "can't combine two of the same type");
return std::tuple<T, U> {};
}
struct A {};
struct B {};
constexpr Wrapper<A> aaa = {};
constexpr Wrapper<B> bbb = {};
constexpr auto shouldPass1 = aaa | bbb;
//constexpr auto shouldFail1 = aaa | aaa; // fails static assert as expected
using shouldFail2 = decltype(aaa | aaa);
// ^ doesn't fail in MSVC2015, or gcc 6.2. does fail in clang 3.9
更新#1:其他问题
Brian建议static_assert
不会在decltype
上下文中发射,因为该值尚未明确实例化。因此,我在下面添加了一个其他测试,以明确实例化shouldFail2
Type ,我认为Brian的逻辑应导致,下面的代码在MSVC2015或GCC 6.2中不会失败。static_assert
失败。这是一个错误,还是我忽略了某些内容? edit:看来,一旦decltype
提取了类型,我们就可以免费使用shouldFail2
,而无需进一步参考operator|
的定义。
shouldFail2 shouldFail3 = {}; // instantiate shouldFail2.
// ^ doesn't fail in MSVC2015 or gcc 6.2.
更新#2
如果我将operator|
的定义更改为使用auto
(或decltype(auto)
)而没有落后返回类型,则decltype
表达式正确使static_assert
在GCC 6.2中失败。但是,此版本未能在MSVC2015中编译(错误C3779,C2088)。编辑:作为W.F.在下面指出,省略落后返回类型是C 14功能。
template<typename T, typename U>
constexpr auto operator|(Wrapper<T>, Wrapper<U>)
{
static_assert(std::is_same<T,U>::value == false, "can't combine two of the same type");
return std::tuple<T, U> {};
}
...
using shouldFail2 = decltype(aaa | aaa);
// ^ now this correctly fails the static_assert in gcc 6.2
我相信GCC和MSVC是正确的,并且Clang不正确。static_assert
不应发射,因为根据[temp.inst]/3的标准:
除非已明确实例化或明确专业化函数模板专业化,否则当在上下文中引用专业化时,函数模板专业化将暗中实例化 需要一个函数定义。
在诸如decltype
之类的未评估上下文中,请呼叫未定义的函数,因此这不是需要存在函数定义的上下文。因此,未实例化专业主体中的static_assert
声明。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 标准c++ assert()是如何工作的,以及如何重新定义它