4

ここにトリッキーな状況があります、そして私はそれを解決するためにどのような方法があるのだろうかと思います

namespace {
  template <class T> 
  struct Template { /* ... */ }; 
}

typedef Template<int> Template;

残念ながら、TemplatetypedefTemplateは名前のない名前空間のテンプレートに干渉します。グローバルスコープで実行しようとするとTemplate<float>、コンパイラはテンプレート名とtypedef名の間にあいまいなエラーを発生させます。

テンプレート名またはtypedef-nameのいずれかを制御することはできません。今、私はそれが可能かどうか知りたいです:

  • グローバル名前空間にtypedefedタイプTemplate(つまり)のオブジェクトを作成します。Template<int>
  • Template<float>グローバル名前空間にそのタイプのオブジェクトを作成します。

名前のない名前空間に何かを追加することは許可されていません。すべてはグローバル名前空間で実行する必要があります。

そのような曖昧さを解決するためにどんなトリックがあるのか​​疑問に思っていたので、これは好奇心からです。それは私が毎日のプログラミング中にぶつかった実際的な問題ではありません。

4

4 に答える 4

1

私はそれがあなたの主張をいくらか台無しにすることを知っています、しかし私は本当に主なトリックは疫病のようなこのようなものを避けることだと思います。

于 2010-05-28T21:33:34.153 に答える
1

C++0x を使用:

namespace {
  template<class T> struct Template { };
}
typedef Template<int> Template;

#include<iostream>

template<typename T> 
void PrintType() { 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
}

template<typename FullType, typename NewParameter>
class Rebind {
  template<template<class> class Template, typename OldParameter>
  static Template<NewParameter> function(Template<OldParameter>);

public:
  typedef decltype(function(FullType())) NewType;
};

int main()
{
  PrintType< ::Template>();
  PrintType<Rebind< ::Template, float>::NewType>();
  return 0;
}

得られるgcc45を使用

void PrintType() [with T = <unnamed>::Template<int>]
void PrintType() [with T = <unnamed>::Template<float>]

どうやらそれは Cormeau でコンパイルされるようですが、私は彼らのオンライン テストにしかアクセスできないので、期待どおりに機能すると仮定して立ち往生しています。

実際の型を構造体に直接渡し、それをテンプレート型に分解する方法はわかりませんでしたが、関数パラメーターを推測する必要がある場合、コンパイラーは問題なく 2 つを削除しました。boost::result_ofおそらく、これはの代わりにC++03 を使用して動作しますがdecltype、これまで使用したことがないので、知っていることに固執すると考えました。

内の間隔に注意してくださいmain。 有向グラフであるRebind<::Template, float>::NewTypeため、パーサーによってむさぼり食われます。<:に変わると思いますRebind[:Template, float>::NewType。そのため、前のスペース::Templateは非常に重要です。

余談ですが、ネストされたテンプレート パラメーターが typename [template<template<typename> class T>ではなくtemplate<template<typename> typename T>] を使用できないとは思いもしませんでした。構成の構文を覚えようとするたびに、それを再学習したと思います。

于 2010-05-29T10:26:48.783 に答える
0

名前空間について明示することで、グローバルなtypedefedテンプレートにアクセスできます。

::Template a

Template<int>匿名の名前空間からです。を取得できるかどうかわからないTemplate<float>

驚くべきことに、 ClangのC ++コンパイラは、おそらく標準的な動作ではなく、次のように問題ありません。

#include <iostream>
namespace {
    template <class T>
        struct Template {T value;};}
typedef Template<int> Template;

int main(){    
    ::Template a;
    Template<float> b;
    a.value = 6;
    b.value = 3.14;
    std::cout<<a.value<<" "<<b.value<<"\n";
}
于 2010-05-28T21:35:59.703 に答える
-1

免責事項:なぜあなたがこれをしたいのかわかりません。おそらく、そうした人には厳しく話すでしょう.

namespace
{
   template <typename T> class Template { };
}

typedef Template<int> IntTemplate;
typedef Template<float> FloatTemplate;
typedef IntTemplate Template;

int main() {
    ::Template t;
    FloatTemplate ft;
}
于 2010-05-28T21:38:18.013 に答える