Как сделать static_assert в шаблонах элементов только тогда, когда они действительно используются? - PullRequest
4 голосов
/ 19 июня 2011

Рассмотрим этот простой класс:

template<class T>
class Foo{
public:
  Foo(T const& val)
    : _val(val) {}

  template<class U>
  Foo(Foo<U> const&){
    static_assert(false,"Cannot convert from Foo<U> to Foo<T>.");
  }

  operator T&() { return _val; }
  operator T const&() const{ return _val; }

private:
  T _val;
};

Это позволяет неявную конструкцию из типа шаблона и неявное преобразование обратно в этот тип, простую оболочку.

Теперь я не хочу включать преобразование между несвязанными Foo с, что было бы возможно из-за этих неявных конструкций / преобразований. Я мог бы сделать шаблонное копирование частным, но я не хотел бы выдавать полезную диагностику через static_assert.

Проблема, как показано здесь на Ideone , заключается в том, что static_assert дает сбой, даже когда я даже не пытаюсь скопировать тип! В Visual Studio я получаю желаемое поведение, хотя думаю, что это связано с тем, как VS анализирует шаблоны. Есть ли способ заставить это работать?

Ответы [ 2 ]

7 голосов
/ 19 июня 2011

Сбой компиляции, потому что компилятор может ясно видеть, что static_assert не сработает, несмотря ни на что.Это никак не зависит от U и T.

Я думаю, вы хотели что-то вроде этого:

static_assert(std::is_same<T,U>::value,"Cannot convert from Foo<U> to Foo<T>.");
2 голосов
/ 30 августа 2012

Кажется, решение - std :: is_convertible.

From http://en.cppreference.com/w/cpp/types/is_convertible:

"Если в выражении return функции можно использовать мнимое значение типа Fromвозвращая To, то есть, если он может быть преобразован в To с использованием неявного преобразования, предоставляет значение константы члена, равное true. В противном случае значение равно false. "

...