当通过decltype表达式调用时,static_assert是否可以工作?

时间:2016-12-07 06:35:50

标签: c++ c++11 decltype static-assert

我希望以下代码失败并在最后一行进行public void returnToInitPosition(final View view) { //return to initial position animation AnimatorSet set = new AnimatorSet(); set.playTogether(---my anims---); //temporary remove of onTouch listener set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); //remove listener on animation start view.setOnTouchListener(null); } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //re-add listener on animation complete view.setOnTouchListener(MyCustomObject.this); } }); //start animation set.start(); } 检查。但是在MSVC2015和gcc 6.2中,它成功编译。它确实无法在clang 3.9中按预期编译。这是编译器错误还是static_assertstatic_assert内无效?

decltype()

更新#1:其他问题

Brian建议#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 不会在static_assert上下文中触发,因为该值尚未显式实例化。所以我在下面添加了一个额外的测试来显式实例化decltype类型,我认为Brian的逻辑会导致shouldFail2失败。但是,代码以下内容在MSVC2015或gcc 6.2中不会失败。 这是一个错误,还是我忽略了什么?编辑:似乎static_assert提取了类型后,我们可以自由使用decltype而无需进一步参考shouldFail2的定义。

operator|

更新#2

如果我将shouldFail2 shouldFail3 = {}; // instantiate shouldFail2. // ^ doesn't fail in MSVC2015 or gcc 6.2. 的定义更改为使用没有尾随返回类型的operator|(或auto),那么decltype(auto)表达式正确地使{{1}失败在gcc 6.2中。但是,此版本无法在MSVC2015中编译(错误C3779,C2088)。编辑:作为W.F.在下面指出,省略尾随返回类型是C ++ 14的功能。

decltype

1 个答案:

答案 0 :(得分:7)

我相信GCC和MSVC是正确的,但Clang是不正确的。 static_assert不应该触发,因为根据[temp.inst] / 3上的标准:

  

除非已明确实例化或明确专门化了函数模板特化,否则在上下文中引用特化时隐式实例化函数模板特化。   需要存在函数定义。

在未评估的上下文(例如decltype)中,调用未定义的函数是有效的,因此这不是需要存在函数定义的上下文。因此,专业化主体中的static_assert声明未实例化。