Предположим, вы хотите, чтобы избежать сужения при вызове функцииИзбегайте по вызову функции
void foo(char c) { /* ... */ }
foo(4); // get a compilation error here
Предположим, вы хотите, чтобы избежать сужения при вызове функцииИзбегайте по вызову функции
void foo(char c) { /* ... */ }
foo(4); // get a compilation error here
Вы можете использовать шаблон класса на T, который имеет
1) конструктор шаблона на другой тип X, который пытается создать экземпляр класса, если параметр не T
2) конструктор с Т, как пары, который заботится о том случае, когда вы инстанцирование класса с точным типом
#include <iostream>
// g++-4.9 -Werror=narrowing -std=c++11 main2.cc
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55783
template <typename T>
struct no_narrowing
{
using type = T;
// this template constructor lets you try to
// instantiate a no_narrowing using a different
// type. if Narrowing would take place
// value{ val } takes care of it
template <typename X>
no_narrowing(X val) : value{val} {}
// if type is exactly T we use this
no_narrowing(type val) : value{val} {}
operator type() const { return value;}
type value;
};
template <typename T>
using nn = no_narrowing<T>;
void print(nn<char> v)
{
std::cout << v << std::endl;
}
int main(int argc, char *argv[])
{
int i = 2;
print('d');
print(i); // this will not compile
return 0;
}
Вы можете определить свою целевую функцию, и перегрузку шаблона переадресации, который будет пытаться не-сужающее преобразование к типу цели (DEMO):
void foo(char) {}
template <typename T>
void foo(T&& t) { foo(char{std::forward<T>(t)}); }
foo('a');
// foo(4); // ill-formed
foo({4});
// foo(0); // ill-formed
foo({0});
// foo(u'a'); // ill-formed
foo({u'a'});
int i = 2;
// foo(i); // ill-formed
// foo({i}); // ill-formed
Это имеет хорошее преимущество, что клиенты могут принудительно преобразуйте самих себя, передав бит-init-list. Поскольку список braced-init препятствует вычитанию шаблона, только целевая функция может быть выбрана с помощью разрешения перегрузки. Так что, хотя, например, foo(4)
соответствует шаблону перегрузки и плохо сформирован. Поскольку int
не может быть преобразован в char
без сужения - foo({4})
хорошо сформирован с 4
может быть преобразован в char
без сужения.