Intereting Posts

std :: make_shared как аргумент по умолчанию не компилируется

В Visual C ++ (2008 и 2010) следующий код не компилируется со следующей ошибкой:

#include  void Foo( std::shared_ptr test = ::std::make_shared( 5 ) ) { } class P { void Foo( std::shared_ptr test = ::std::make_shared( 5 ) ) { } }; 

ошибка C2039: ‘make_shared’: не является членом “ глобального пространства имен ”

ошибка C3861: ‘make_shared’: идентификатор не найден

Он жалуется на определение P :: Foo () not :: Foo ().

Кто-нибудь знает, почему это действительно для Foo (), чтобы иметь аргумент по умолчанию с std :: make_shared, но не P :: Foo ()?

Это похоже на ошибку в компиляторе. Вот минимальный код, необходимый для воспроизведения проблемы:

 namespace ns { template  class test { }; template  test func() { return test(); } } // Works: void f(ns::test = ns::func()) { } class test2 { // Doesn't work: void g(ns::test = ns::func()) { } }; 

Visual C ++ 2008 и 2010 оба отчета:

ошибка C2783: ‘ ns::test ns::func(void) ‘: не удалось вывести аргумент шаблона для ‘ T

У Комо нет проблем с этим кодом.

Я попал в ту же проблему, что и в моем собственном коде. Минимальный код, который я откинул, был следующим:

 namespace N { template T defaultValue() { return T(); } template void fun( const T& value = N::defaultValue() ){} } int main(int argc, char* argv[]) { N::fun(); return 0; } 

Это немного отличается от примера Джеймса Макнеллиса – и, я думаю, подчеркивает тот факт, что это квалификация пространства имен в инициализаторе аргументов по умолчанию, где это происходит неправильно.

В этом случае defaultValue и fun находятся в одном пространстве имен, поэтому вы можете тривиально удалить N :: из N :: defaultValue, и он работает.

Если defaultValue находится в другом пространстве имен, вы все равно можете его обойти, либо введя его в локальное пространство имен с использованием, либо создав функцию локального шаблона пересылки, например:

 namespace N1 { template T defaultValue() { return T(); } } namespace N2 { template T defaultValueFwd() { return N1::defaultValue(); } template void fun( const T& value = defaultValueFwd() ){} } int main(int argc, char* argv[]) { N2::fun(); return 0; } 

Немного боль, но работоспособная. Я считаю, что вы можете использовать эту технику в случае make_shared, хотя я этого не пробовал.