visual-studio-2010 - 函数声明中的 static_assert

标签 visual-studio-2010 templates c++11 generic-programming static-assert

我使用 static_assert 得到了一个相当简单的函数.麻烦的是我要static_assert关于函数声明中涉及的行为——特别是推断返回类型。似乎没有任何地方可以插入 static_assert这样我就可以在编译器无法推断返回类型之前触发它。

到目前为止,我将返回类型推导和静态断言放在一个结构中。这将触发断言,这很好,但它仍然会在类型推导中产生错误,这是我想要消除的噪音。

#include <type_traits>
#include <functional>
#include <memory>
#include <map>
#include <iostream>
#include <string>
#include <cstdio>
#include <tuple>
#include <sstream>
#include <vector>
#include <algorithm>

template<typename T, typename X> struct is_addable {
    template<typename Test, typename Test2> static char test(decltype(*static_cast<Test*>(nullptr) + *static_cast<Test2*>(nullptr))*);
    template<typename Test, typename Test2> static int test(...);
    static const bool value = std::is_same<char, decltype(test<T, X>(nullptr))>::value;
};
template<typename T, typename X> struct is_addable_fail {
    static const bool value = is_addable<T, X>::value;
    static_assert(value, "Must be addable!");
    typedef decltype(*static_cast<T*>(nullptr) + *static_cast<X*>(nullptr)) lvalue_type;
};

template<typename T1, typename T2> auto Add(T1&& t1, T2&& t2) -> typename is_addable_fail<T1, T2>::lvalue_type {
    return std::forward<T1>(t1) + std::forward<T2>(t2);
}

struct f {};

int main() {
    std::cout << Add(std::string("Hello"), std::string(" world!"));
    Add(f(), f());
}

最佳答案

由于候选集的构建方式和 SFINAE,这是不可能的。如果您可以在完全确定函数签名之前断言,那么这将要求您在决定该函数是将要使用的函数之前进行断言。

步骤的顺序基本上是:

  • 查找匹配函数
  • 将推导的参数替换为函数参数和返回类型。
  • 丢弃那些失败的 (SFINAE)
  • 如果剩下一个,请使用它。

  • 您希望断言何时触发?

    如果您在参数替换期间触发它,那么您就排除了 SFINAE,如果您在此之后的任何时间触发它,则返回类型已经确定(为时已晚)。

    关于visual-studio-2010 - 函数声明中的 static_assert,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6497124/

    相关文章:

    c++ - 非指针函数类型可以是非类型参数吗?

    c++ - 连接 vector 的 Constexpr 函数

    C++ 不同的 minmax 实现

    c++ - 我有一个未声明的标识符错误,我无法弄清楚

    c++ - Microsoft C++ 预定义宏

    参数替换的 C++ 规则

    c++ - 无法从 initializer_list 转换为我的类型,该类型具有模板化可变参数构造函数

    c++ - 别名方法和性能问题

    c++ - 完成后如何在不运行exe文件的情况下编译项目?

    c++ - 为什么 std::bind 不考虑功能元数?