質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1160閲覧

転送参照(ユニバーサル参照)にしたくない

tails

総合スコア22

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

2クリップ

投稿2021/08/08 10:56

前提・実現したいこと

次のようなテンプレート関数で、非const右辺値のみを受け取り可能にしたい。

C++

1#include <utility> 2 3template <class T> void f(T&&); 4 5int main() { 6 int value = 0; 7 const int const_value = 0; 8 9 f(value); // エラーにしたい 10 f(std::move(value)); // これだけOKにしたい 11 12 f(const_value); // エラーにしたい 13 f(std::move(const_value)); // エラーにしたい 14}

質問

以下のようにdeleted定義を利用することで実現できますが、もっと単純に書けないのでしょうか。
ただ単に、転送参照にして欲しくなくて、非テンプレート型Sに対するS&&のように、右辺値を受け取りたいだけなのですが…

C++

1template <class T> void test(T&&); 2template <class T> void test(T&) = delete; 3template <class T> void test(const T&&) = delete;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ユニバーサル参照を直接的に禁止する方法はないです。

ユニバーサル参照として受け取った上で制約を付けることは出来ますが、見ての通りあまり見通しが良くないので「もっと単純に書けないのでしょうか」という質問に対してこの方法が単純な手法とはちょっと言い難いですね。 (C++20 以降ならコンセプトを使えるので少しは簡単になるはずですが……)

面倒でも delete を活用するほうがよりよい作法に思われます。

cpp

1#include <utility> 2#include <type_traits> 3 4template <class T> 5typename std::enable_if<not std::is_const<typename std::remove_reference<T>::type>::value && not std::is_lvalue_reference<T>::value>::type f(T&&){ 6} 7 8int main() { 9 int value = 0; 10 const int const_value = 0; 11 12 f(value); // エラーにしたい 13 f(std::move(value)); // これだけOKにしたい 14 15 f(const_value); // エラーにしたい 16 f(std::move(const_value)); // エラーにしたい 17}

投稿2021/08/08 13:53

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tails

2021/08/10 15:59

そうなんですね… 分かりました、残念です。 諦めます。
guest

0

参考までにC++20コンセプトを用いた制約テンプレートの実装(例)です。

c++

1#include <concepts> 2#include <type_traits> 3 4template <class T> 5 requires std::is_rvalue_reference_v<T&&> && std::same_as<std::remove_cv_t<T>, T> 6void f(T&&);

投稿2021/08/11 02:41

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tails

2021/08/26 09:05

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問