У меня довольно простая функция, использующая 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());
}