I've got quite a simple function using static_assert
. The trouble is that I want to static_assert
on behaviour involved in the function declaration- inferring the return type, specifically. There don't seem to be any places to interject the static_assert
so that I can fire it before the compiler fails to deduce the return type.
So far, I put return type deduction and the static assertion in a struct. This will fire the assertion, which is great, but it'll still generate an error on the type deduction, which is noise I want to eliminate.
#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());
}
It's not possible because of the way candidate sets are built and SFINAE. If you could assert before a function's signature has fully been determined then that would require you to assert before it has been decided that the function is the one that is going to be used.
The order of steps is essentially:
When do you want the assert to fire?
If you fire it during parameter substitution then you are ruling out SFINAE, and if you fire it any time after that then the return type has already been determined (too late).