Определение того, проходит ли временный - PullRequest
1 голос
/ 24 августа 2011

Допустим, у меня есть класс C и функция make_c(x), которая создает экземпляры C.

C хранит x по ссылке.

Как мне написать make_c(x), чтобы выдать ошибку компиляции, когда x - это неназванный временный объект (который, конечно, будет разрушаться в конце строки, оставляя висячую ссылку), но принимать именованные временные и другие значения?

Ответы [ 3 ]

5 голосов
/ 24 августа 2011

Я считаю, что это должно иметь семантику, которую вы ищете:

template<typename X>
C make_c(X&& x)
{
    static_assert(
        !std::is_rvalue_reference<decltype(std::forward<X>(x))>::value,
        "x must not be a temporary"
    );
    return C(std::forward<X>(x));
}

Предупреждение: это не будет работать как есть с VC ++ 2010 из-за недостатков в реализации decltype (вынужно обернуть decltype в std::identity<>).

1 голос
/ 24 августа 2011

Я не думаю, что это возможно в языке, потому что вам нужно проверить управление потоком через произвольные функции.

struct Foo{
};

Foo const & sanitize(Foo const & f){ return f;}

void checkThisFunction(Foo const & f){
   //we'd like to ensure at compile time that f is not a temporary
}

int main(){
   Foo f;
   checkThisFunction(sanitize(f));
   checkThisFunction(sanitize(Foo()));
   return 0;
}
0 голосов
/ 24 августа 2011

Если я не совсем неверно понимаю rvalue ссылки, такого рода вещи должны быть выполнимы с простой перегрузкой.

void foo(int&&) = delete;
void foo(const int&) { }

int main()
{
   int a;
   foo(a);
   foo(42);  //error, prefers binding to the deleted overload
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...