LINUX.ORG.RU

История изменений

Исправление Kroz, (текущая версия) :

Общая реализация и с тем, и с другим, специализация без копирования

У меня класс немаленький, плюс в шаблоне 2 типа: нужно будет специализацию делать по обоим, ибо по одному нельзя.

Пока написал такой КОСТЫЛИЩЕ.

template<bool icc>
class CMoveCopyDetector{
public:
	template<class T>
	inline static T MoveCopy(T &v)
	{
		T result(v);

		return result;
	};
	
};
template<>
class CMoveCopyDetector<false>{
public:
	template<class T>
	inline static T&& MoveCopy(T &&v)
	{
		THROW("ELogicError: You should not get here, since the value type has no copy constructor.");
		throw ELogicError();
		//return std::move(v);
	};
	
};


template<class TValue, typename TIndex>
TIndex CSet<TValue,TIndex>::Add(const TValue &value)
{
	FUNCTION("&value");
	
	TIndex result;
	
	result=Add( std::move(  CMoveCopyDetector< std::is_copy_constructible<TValue>::value >::MoveCopy(value)   ) );
	
	RETURN(result);
	return result;
}

Работает. Правда, если убрать исключение и раскомментровать return, то при неправильном использовании TValue (без std::move, несмотря на отсутствие конструктора копирования) входит в бесконечную рекурсию (Add() вызывает сама себя), не совсем понятно почему.

Должен быть вариант получше...

Исходная версия Kroz, :

Общая реализация и с тем, и с другим, специализация без копирования

У меня класс немаленький, плюс в шаблоне 2 типа: нужно будет специализацию делать по обоим, ибо по одному нельзя.

Пока написал такой КОСТЫЛИЩЕ.

template<bool icc>
class CMoveCopyDetector{
public:
	template<class T>
	inline static T MoveCopy(T &v)
	{
		T result(v);

		return result;
	};
	
};
template<>
class CMoveCopyDetector<false>{
public:
	template<class T>
	inline static T&& MoveCopy(T &&v)
	{
		THROW("ELogicError: You should not get here, since the value type has no copy constructor.");
		throw ELogicError();
		//return std::move(v);
	};
	
};


template<class TValue, typename TIndex>
TIndex CSet<TValue,TIndex>::Add(const TValue &value)
{
	FUNCTION("&value");
	
	TIndex result;
	
	result=Add( std::move(  CMoveCopyDetector< std::is_copy_constructible<TValue>::value >::MoveCopy(value)   ) );
	
	RETURN(result);
	return result;
}

Работает. Правда, если убрать исключение и раскомментровать return, то при неправильном использовании CValue (без std::move, несмотря на отсутствие конструктора копирования) входит в бесконечную рекурсию (Add() вызывает сама себя), не совсем понятно почему.

Должен быть вариант получше...